Building a GraphQL API with Deno and gql

deno-libs
/
gql

☁ Universal GraphQL HTTP middleware for Deno

gql

Universal GraphQL HTTP middleware for Deno.

Features

✨ Works with std/http, tinyhttp an…

GitHub logo

deno-libs
/
gql

☁ Universal GraphQL HTTP middleware for Deno

gql

GitHub release (latest by date) GitHub Workflow Status
Codecov

Universal GraphQL HTTP middleware for Deno.

Features

Get started

Vanilla

The simplest setup with std/http:

import { serve } from 'https://deno.land/std@0.90.0/http/server.ts'
import { GraphQLHTTP } from 'https://deno.land/x/gql/mod.ts'
import { makeExecutableSchema } from 'https://deno.land/x/graphql_tools/mod.ts'
import { gql } from 'https://deno.land/x/graphql_tag/mod.ts'
const typeDefs = gql`
  type Query {
    hello: String
  }
`
const resolvers = {
  Query: {
    hello: () => `Hello World!`
  }
}
const schema = makeExecutableSchema({ resolvers, typeDefs })
const s = serve({ port: 3000 })

for await (const req of s) {
  req.url.startsWith('/graphql')
    ? await GraphQLHTTP({
        schema,
        graphiql: true
      })(req)
    : req.respond({
        status: 404
      }

In this post I would like to show how to build a GraphQL API server with gql.
At the moment there are a few GraphQL server modules for Deno, such as obsidian and oak_graphql but all of them are either standalone or framework-specific.
gql instead, is a framework-agnostic middleware so I will use it with Deno std’s net/http.



GraphQL Schema

We’ll start with declaring a schema using type definitions and resolvers using graphql_tag and graphql_tools Deno modules, similar to how you do it with Apollo Server or GraphQL Yoga:

import { makeExecutableSchema } from 'https://deno.land/x/graphql_tools/mod.ts'
import { gql } from 'https://deno.land/x/graphql_tag/mod.ts'

/* Type definitions */
const typeDefs = gql`
  type Query {
    hello: String
  }
`

/* Resolvers */
const resolvers = {
  Query: {
    hello: () => `Hello World!`
  }
}

const schema = makeExecutableSchema({ resolvers, typeDefs })

Now we have an executable schema that can be passed to a GraphQL server.



Server setup

In order to setup gql you just need to pass a req object to it so it can read request body and properties.

import { serve } from 'https://deno.land/std@0.90.0/http/server.ts'
import { GraphQLHTTP } from 'https://deno.land/x/gql/mod.ts'
import { makeExecutableSchema } from 'https://deno.land/x/graphql_tools/mod.ts'
import { gql } from 'https://deno.land/x/graphql_tag/mod.ts'

const typeDefs = gql`
  type Query {
    hello: String
  }
`

const resolvers = {
  Query: {
    hello: () => `Hello World!`
  }
}

const schema = makeExecutableSchema({ resolvers, typeDefs })

const s = serve({ port: 3000 })

for await (const req of s) {
  req.url.startsWith('/graphql')
    ? await GraphQLHTTP({
        schema,
        graphiql: true // enable GraphQL playground
      })(req)
    : req.respond({
        status: 404
      })

Now run the server with these permissions (for reading body and using network):

deno run --allow-net --allow-read server.ts



GraphQL Playground

Now when then server is up, the GraphQL Playground will launch as well.

Open your favourite browser on http://localhost:3000 and you will see this:

playground image



Server Context

It’s also possible to pass request context to a schema so it could be used in resolvers.
Request object is automatically passed to the context function.

import { serve, ServerRequest } from 'https://deno.land/std@0.90.0/http/server.ts'
import { GraphQLHTTP } from 'https://deno.land/x/gql/mod.ts'
import { makeExecutableSchema } from 'https://deno.land/x/graphql_tools/mod.ts'
import { gql } from 'https://deno.land/x/graphql_tag/mod.ts'

const typeDefs = gql`
  type Query {
    hello: String
  }
`

const resolvers = {
  Query: {
    hello: (root, args, ctx) => `Hello World from ${ctx.url}! Cusotm context property ${ctx.ctxProp}`
  }
}

const schema = makeExecutableSchema({ resolvers, typeDefs })

const s = serve({ port: 3000 })

for await (const req of s) {
  req.url.startsWith('/graphql')
    ? await GraphQLHTTP<ServerRequest>({
        schema,
        graphiql: true // enable GraphQL playground,
        context: (request) => ({
          request, // request object
          ctxProp: 'ctxValue' // aditional context properties
        })
      })(req)
    : req.respond({
        status: 404
      })



Conclusion

This is how you can set up a simple GraphQL server for Deno without any backend frameworks, just net/http.
Although, there are a few examples of using gql with other frameworks, check them out.


Print Share Comment Cite Upload Translate
APA
v 1 r t l | Sciencx (2024-03-29T12:37:20+00:00) » Building a GraphQL API with Deno and gql. Retrieved from https://www.scien.cx/2021/04/13/building-a-graphql-api-with-deno-and-gql/.
MLA
" » Building a GraphQL API with Deno and gql." v 1 r t l | Sciencx - Tuesday April 13, 2021, https://www.scien.cx/2021/04/13/building-a-graphql-api-with-deno-and-gql/
HARVARD
v 1 r t l | Sciencx Tuesday April 13, 2021 » Building a GraphQL API with Deno and gql., viewed 2024-03-29T12:37:20+00:00,<https://www.scien.cx/2021/04/13/building-a-graphql-api-with-deno-and-gql/>
VANCOUVER
v 1 r t l | Sciencx - » Building a GraphQL API with Deno and gql. [Internet]. [Accessed 2024-03-29T12:37:20+00:00]. Available from: https://www.scien.cx/2021/04/13/building-a-graphql-api-with-deno-and-gql/
CHICAGO
" » Building a GraphQL API with Deno and gql." v 1 r t l | Sciencx - Accessed 2024-03-29T12:37:20+00:00. https://www.scien.cx/2021/04/13/building-a-graphql-api-with-deno-and-gql/
IEEE
" » Building a GraphQL API with Deno and gql." v 1 r t l | Sciencx [Online]. Available: https://www.scien.cx/2021/04/13/building-a-graphql-api-with-deno-and-gql/. [Accessed: 2024-03-29T12:37:20+00:00]
rf:citation
» Building a GraphQL API with Deno and gql | v 1 r t l | Sciencx | https://www.scien.cx/2021/04/13/building-a-graphql-api-with-deno-and-gql/ | 2024-03-29T12:37:20+00:00
https://github.com/addpipe/simple-recorderjs-demo