Repository: mcollina/fastify-gql
Pull request #26 (2019-01-06 19:45:57)

Add defineMutation option
This is a proposition to solve #25 


Patch:
diff --git a/README.md b/README.md
index 1766bbb..2a74772 100644
--- a/README.md
+++ b/README.md
@@ -104,6 +104,7 @@ __fastify-gql__ supports the following options:
 * `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
 
@@ -208,7 +209,7 @@ const GQL = require('fastify-gql')
 
 const app = Fastify()
 const schema = `
-  type Query {
+  extend type Query {
     add(x: Int, y: Int): Int
   }
 `
diff --git a/index.js b/index.js
index 96f3005..49b154f 100644
--- a/index.js
+++ b/index.js
@@ -54,7 +54,11 @@ module.exports = fp(async function (app, opts) {
       query: new GraphQLObjectType({
         name: 'Query',
         fields: { }
-      })
+      }),
+      mutation: opts.defineMutation ? new GraphQLObjectType({
+        name: 'Mutation',
+        fields: { }
+      }) : undefined
     })
   }
 


Test patch:
diff --git a/test/app-decorator.js b/test/app-decorator.js
index cb2a1bf..5d649ee 100644
--- a/test/app-decorator.js
+++ b/test/app-decorator.js
@@ -3,6 +3,8 @@
 const { test } = require('tap')
 const Fastify = require('fastify')
 const GQL = require('..')
+const { GraphQLError } = require('graphql')
+
 const {
   GraphQLScalarType,
   GraphQLEnumType
@@ -146,7 +148,7 @@ test('operationName', async (t) => {
   })
 })
 
-test('extendSchema and defineResolvers', async (t) => {
+test('extendSchema and defineResolvers for query', async (t) => {
   const app = Fastify()
   const schema = `
     extend type Query {
@@ -178,6 +180,74 @@ test('extendSchema and defineResolvers', async (t) => {
   })
 })
 
+test('extendSchema and defineResolvers with mutation definition', async (t) => {
+  const app = Fastify()
+  const schema = `
+    extend type Query {
+      add(x: Int, y: Int): Int
+    }
+    extend type Mutation {
+      sub(x: Int, y: Int): Int
+    }
+  `
+
+  const resolvers = {
+    add: async ({ x, y }) => x + y,
+    sub: async ({ x, y }) => x - y
+  }
+
+  app.register(GQL, { defineMutation: true })
+
+  app.register(async function (app) {
+    app.graphql.extendSchema(schema)
+    app.graphql.defineResolvers(resolvers)
+  })
+
+  // needed so that graphql is defined
+  await app.ready()
+
+  const mutation = 'mutation { sub(x: 2, y: 2) }'
+  const res = await app.graphql(mutation)
+
+  t.deepEqual(res, {
+    data: {
+      sub: 0
+    }
+  })
+})
+
+test('extendSchema and defineResolvers throws without mutation definition', async (t) => {
+  const app = Fastify()
+  const schema = `
+    extend type Query {
+      add(x: Int, y: Int): Int
+    }
+    
+    type Mutation {
+      sub(x: Int, y: Int): Int
+    }
+  `
+
+  const resolvers = {
+    add: async ({ x, y }) => x + y,
+    sub: async ({ x, y }) => x - y
+  }
+
+  app.register(GQL)
+
+  app.register(async function (app) {
+    app.graphql.extendSchema(schema)
+    app.graphql.defineResolvers(resolvers)
+  })
+
+  // needed so that graphql is defined
+  await app.ready()
+
+  const mutation = 'mutation { sub(x: 2, y: 2) }'
+
+  t.rejects(app.graphql(mutation), GraphQLError)
+})
+
 test('basic GQL no cache', async (t) => {
   const app = Fastify()
   const schema = `