Introducing the GraphQL Handler

Ultimately, in order to be able to execute GraphQL queries you need a GraphQL handler. This handler accepts a query and variables and returns a payload of data and/or errors.

The GraphQL Handler is also the glue between many pieces of the mocking framework, like Resolver Maps, Resolver Map Middlewares, Resolver Wrappers and Network Handlers, which are covered in the following sections.

Installation

# npm
npm install --save-dev graphql-mocks
# yarn
yarn add --dev graphql-mocks

Double-check that you've installed the graphql-mocks package also.

Getting started

The GraphQLHandler is available from the core graphql-mocks package.

import { GraphQLHandler } from 'graphql-mocks';
import schema from './schema';
const handler = new GraphQLHandler({
dependencies: {
graphqlSchema: schema
}
});

GraphQL Schema

A GraphQL Schema is a required dependency for setting up the handler.

The schema can be:

  • an instance of GraphQLSchema provided by the graphql package
  • a GraphQL Schema AST (sometimes what is provided by babel loaders or bundlers)
  • a string that is formatted in GraphQL SDL (Schema Definition Language)
const handler = new GraphQLHandler({
dependencies: {
graphqlSchema: schema,
// include other dependencies by key,
// like a `Paper` instance of graphql-paper store, for example.
paper: Paper
}
});

Dependencies

As stated above some form of a GraphQL Schema is a required dependency for the GraphQLHandler. Aside from this, other Resolver Map Middlewares, Resolver Wrappers, or Resolvers may require their own dependencies. These can be listed on the dependencies object passed into the GraphQLHandler.

These dependencies can also be accessed from the context within a Resolver (see Managing Resolver Context for more information).

Resolver Map

A base Resolver Map can be optionally included with the GraphQL Handler. It can then be used for subsequent Resolver Map Middlewares.

const resolverMap = {};
const handler = new GraphQLHandler({
resolverMap: resolverMap,
dependencies: {
graphqlSchema: schema
}
});

See Using Resolver Maps to learn more about Resolver Maps, and Introducing Resolver Map Middlewares on how they can be extended with Middlewares.

Querying

Calling the query method (with queries or mutations) on a GraphQLHandler will return a promise with a payload (data or errors). The first argument of query method takes a string representing the operation (a query or mutation). The second argument is an object representing the variables used for the query.

Learn more about queries and mutations from the official GraphQL Documentation

Note: The variable names in the object must match the the names at the top of the operation without the $. In the following example the $name variable passed in at the top of the query has a matching name property in the variables object.

Note: Additional context can be passed on a per-query basis, see Managing Resolver Context for details.

const query = `
query($name: String!) {
hello(name: $name)
}
`;
const variables = {
name: 'Simone'
};
// handler as an instance of GraphQLHandler
const result = await handler.query(query, variables);

Example

This example follows the most basic path of creating custom resolvers that many GraphQL tutorials follow. While this shows the handler in use keep in mind that the GraphQLHandler is also used with Middlewares and Wrappers to flexibly cover many different use-cases and scenarios.

import { GraphQLHandler } from "graphql-mocks";
const schemaString = `
schema {
query: Query
}
type Query {
helloWorld: String!
}
`;
const resolverMap = {
Query: {
helloWorld() {
return "Hello from my first GraphQL resolver!";
},
},
};
const handler = new GraphQLHandler({
resolverMap,
dependencies: {
graphqlSchema: schemaString,
},
});
const query = handler.query(
`
{
helloWorld
}
`
);
query.then((result) => console.log(result));
Result:
{
  "data": {
    "helloWorld": "Hello from my first GraphQL resolver!"
  }
}