GraphQL resolve method

This post will describe the resolve method which will be invoked by the GraphQL execution engine in order to populate data for the request.

When you write your GraphQL schema, you will have to provide the resolve method which will be invoked by the GraphQL execution engine when data are actually queried.

The first time you encounter the resolve method is when you define your Query types. The good news is that the resolve method is the same in all its instances.

Here is a simple schema:

var queryType = new GraphQLObjectType({
  name: 'RootQueryType',
  fields: () => ({
    user: {
      type: UserType,
      description: 'the users of the service',
      args: {
        id: {
          name: 'id',
          type: new GraphQLNonNull(GraphQLString)
        }
      },
      resolve: (parent, args, ast) => {
        /* code goes here */
      }
    },

The call of the resolve method is done in the method resolveOrError in graph-ql-js and we see that the parameters are :

source: any,
args: { [key: string]: any },
info: GraphQLResolveInfo

parameter: source

For a Query type, this is the rootValue that you pass in when starting your server.

app.use('/graphql', graphqlHTTP(function() {
  return {
    schema: schema,
    rootValue: {
      message: 'hello world!'
    }
  };
}));

For the other types, this field is the parent instance which has just been fetched (to be confirmed).

This parameter has been renamed to parent to reflect describe its nature.

parameter: args

This parameter contains the arguments of your query.

For instance, with that query:

{
  user(id: "1") {
    id
    name
  }
}

We have those values:

- parent:{ message: 'hello world!' }
-   args:{ id: '1' }

parameter: info

This one is trickier. It has been renamed into ast in the resolve method because this parameter contains the Abstract Syntax Tree bits associated to the request.

The formal type definition can be found in the code defining the types:

export type GraphQLResolveInfo = {
  fieldName: string,
  fieldASTs: Array<Field>,
  returnType: GraphQLOutputType,
  parentType: GraphQLCompositeType,
  schema: GraphQLSchema,
  fragments: { [fragmentName: string]: FragmentDefinition },
  rootValue: any,
  operation: OperationDefinition,
  variableValues: { [variableName: string]: any },
}

This type is complex but VERY important,

If you want to optimise your queries: you need to parse this structure to find the actual attributes that the user is querying. If you are backed by a SQL database, that will allow you to query only the columns you are interested in.

I am still trying to make sense of this structure and a future post will describe how to parse it.

In the meantime, there is an interesting discussion on this topic here.