Fastify barebone GraphQL adapter
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.

README.md

fastify-gql

Greenkeeper badge

Fastify barebone GraphQL adapter. Queries are cached on reuse to reduce the overhead of query parsing and validation. fastify-gql supports a Just-In-Time compiler via graphql-jit.

Install

npm i fastify fastify-gql

Example

'use strict'

const Fastify = require('fastify')
const GQL = require('fastify-gql')

const app = Fastify()

const schema = `
  type Query {
    add(x: Int, y: Int): Int
  }
`

const resolvers = {
  Query: {
    add: async (_, { x, y }) => x + y
  }
}

app.register(GQL, {
  schema,
  resolvers
})

app.get('/', async function (req, reply) {
  const query = '{ add(x: 2, y: 2) }'
  return reply.graphql(query)
})

app.listen(3000)

See test.js for more examples, docs are coming.

makeExecutableSchema support

'use strict'

const Fastify = require('fastify')
const GQL = require('fastify-gql')
const { makeExecutableSchema } = require('graphq-tools')

const app = Fastify()

const typeDefs = `
  type Query {
    add(x: Int, y: Int): Int
  }
`

const resolvers = {
  Query: {
    add: async (_, { x, y }) => x + y
  }
}

app.register(GQL, {
  schema: makeExecutableSchema({ typeDefs, resolvers })
})

app.get('/', async function (req, reply) {
  const query = '{ add(x: 2, y: 2) }'
  return reply.graphql(query)
})

app.listen(3000)

API

plugin options

fastify-gql supports the following options:

  • schema: String or schema definition. The graphql schema. The string will be parsed.
  • resolvers: Object. The graphql resolvers.
  • graphiql: boolean. Serve GraphiQL on /graphiql if routes is true.
  • jit: Intenger. The minimum number of execution a query needs to be executed before being jit'ed.
  • routes: boolean. Serves the Default: true. A graphql endpoint is exposed at /graphql.
  • prefix: String. Change the route prefix of the graphql endpoint if enabled.
  • defineMutation: Boolean. Add the empty Mutation definition if schema is not defined (Default: false).

HTTP endpoints

GET /graphql

Executed the GraphQL query passed via query string parameters. The supported query string parameters are:

  • query, the GraphQL query.
  • operationName, the operation name to execute contained in the query.
  • variables, a JSON object containing the variables for the query.

POST /graphql

Executes the GraphQL query or mutation described in the body. The payload must conform to the following JSON schema:

{
  type: 'object',
  properties: {
    query: {
      type: 'string',
      description: 'the GraphQL query'
    },
    operationName: {
      type: 'string'
    },
    variables: {
      type: ['object', 'null'],
      additionalProperties: true
    }
  }
}

GET /graphiql

Serves GraphiQL if enabled by the options.

decorators

fastify-gql adds the following decorators.

app.graphql(source, context, variables, operationName)

Decorate Server with a graphql method. It calls the upstream graphql() method with the defined schema, and it adds { app } to the context.

const Fastify = require('fastify')
const GQL = require('fastify-gql')

const app = Fastify()
const schema = `
  type Query {
    add(x: Int, y: Int): Int
  }
`

const resolvers = {
  Query: {
    add: async (_, { x, y }) => x + y
  }
}

app.register(GQL, {
  schema,
  resolvers
})

async function run () {
  // needed so that graphql is defined
  await app.ready()

  const query = '{ add(x: 2, y: 2) }'
  const res = await app.graphql(query)

  console.log(res)
  // prints:
  //
  // {
  //   data: {
  //      add: 4
  //   }
  // }
}

run()

app.graphql.extendSchema(schema) and app.graphql.defineResolvers(resolvers)

It is possible to add schemas and resolvers in separate fastify plugins, like so:

const Fastify = require('fastify')
const GQL = require('fastify-gql')

const app = Fastify()
const schema = `
  extend type Query {
    add(x: Int, y: Int): Int
  }
`

const resolvers = {
  Query: {
    add: async (_, { x, y }) => x + y
  }
}

app.register(GQL)

app.register(async function (app) {
  app.graphql.extendSchema(schema)
  app.graphql.defineResolvers(resolvers)
})

async function run () {
  // needed so that graphql is defined
  await app.ready()

  const query = '{ add(x: 2, y: 2) }'
  const res = await app.graphql(query)

  console.log(res)
  // prints:
  //
  // {
  //   data: {
  //      add: 4
  //   }
  // }
}

run()

reply.graphql(source, context, variables, operationName)

Decorate Reply with a graphql method. It calls the upstream graphql() function with the defined schema, and it adds { app, reply } to the context.

const Fastify = require('fastify')
const GQL = require('fastify-gql')

const app = Fastify()
const schema = `
  type Query {
    add(x: Int, y: Int): Int
  }
`

const resolvers = {
  add: async ({ x, y }) => x + y
}

app.register(GQL, {
  schema,
  resolvers
})

app.get('/', async function (req, reply) {
  const query = '{ add(x: 2, y: 2) }'
  return reply.graphql(query)
})

async function run () {
  const res = await app.inject({
    method: 'GET',
    url: '/'
  })

  console.log(JSON.parse(res.body), {
    data: {
      add: 4
    }
  })
}

run()

License

MIT