Lesson 13 / 25

Resolvers

A function per field.

How execution walks the query

Each field in the schema can have a resolver function receiving (parent, args, context, info): the parent object, the field's arguments, a per-request context and query metadata. Execution starts at root fields and calls resolvers for nested fields with the parent's result; fields without a resolver simply read the property of the same name. Resolvers may return values or promises, so independent fields resolve concurrently. Libraries include Apollo Server, GraphQL Yoga (JavaScript), Strawberry and Graphene (Python), graphql-java and Spring for GraphQL, gqlgen (Go) and Hot Chocolate (.NET).

Resolvers do the work

Resolvers fetch each field, context carries request state, and batching keeps database load reasonable.

Three ideas: resolvers, context and authorisation, DataLoader.
Figure 5.1 — Resolvers, context and batching.

Resolvers with Apollo Server

JavaScript sketch based on the Apollo Server 4 API; check the docs for your version.

import { ApolloServer } from "@apollo/server";
import { startStandaloneServer } from "@apollo/server/standalone";

const typeDefs = `#graphql
  type Product { id: ID!  name: String!  price: Float! }
  type Query { product(id: ID!): Product  products: [Product!]! }
`;

const resolvers = {
  Query: {
    product: (_parent, { id }, { db }) => db.products.findById(id),
    products: (_parent, _args, { db }) => db.products.findAll(),
  },
};

const server = new ApolloServer({ typeDefs, resolvers });
const { url } = await startStandaloneServer(server, {
  context: async ({ req }) => ({ db, user: await authenticate(req) }),
  listen: { port: 4000 },
});

Keep resolvers thin

Put business logic in a service layer shared with other APIs; resolvers should translate between GraphQL and that layer.

Quick check: What is the first argument passed to a field resolver?

  • The HTTP request
  • The parent object (the result of the enclosing field)
  • The database connection
  • The schema
Answer

The parent object (the result of the enclosing field) — parent, args, context, info.