What Are Resolvers?

Resolvers are functions that provide the values requested by GraphQL operations.

Consider this schema:

type Query {
  user(id: ID!): User
}

type User {
  id: ID!
  name: String!
  email: String!
}

A resolver implementation might conceptually look like:

const resolvers = {
  Query: {
    user: async (_, args) => {
      return userRepository.findById(args.id);
    }
  }
};

The schema defines the contract. The resolver provides the behavior.

A resolver can retrieve data from almost anywhere:

  • MongoDB
  • PostgreSQL
  • Redis
  • Another REST API
  • Another GraphQL API
  • An in-memory cache
  • A message or event system
  • A computed value

Resolvers therefore act as an important boundary between the GraphQL API layer and the application's domain/data layers.

A common architectural mistake is putting all business logic directly inside resolver functions. Resolvers should generally coordinate the request rather than becoming enormous business-service functions.

Basic Resolver
const resolvers = {
  Query: {
    user: async (_, args) => {
      return userRepository.findById(args.id);
    }
  }
};
💡 The user resolver receives the field arguments and uses them to obtain a user. The resolver does not need to know how the repository stores the data. Keeping persistence behind a repository or service makes the GraphQL layer easier to maintain and test.
Key Takeaways
  • Resolvers provide values for schema fields.
  • Resolvers can call any appropriate data source.
  • The schema defines the contract while resolvers provide behavior.
  • Complex business logic is usually better placed in service/domain layers.
Knowledge Check

What is the relationship between a GraphQL schema and a resolver?