What is a Field Resolver in GraphQL? A Guide with Example in Node.js

- Published on

Introduction
In GraphQL, field resolvers are the core mechanism that returns data for each field requested by the client. This article explains what resolvers are, why they are important, and shows a small Node.js example implementing both a top‑level query resolver and a nested field resolver.
What is a Field Resolver?
A resolver is a function that resolves the value for a field in a GraphQL schema. Every field can have its own resolver, giving you fine‑grained control over fetching and transforming data.
Example query:
{
user(id: "1") {
name
age
address {
city
state
}
}
}
In this query, user
is a top‑level field that returns a User
. The nested address
field can have its own resolver to fetch related data.
Why resolvers matter:
- Customization and control per field (DB access, external APIs, transformations)
- Efficiency via lazy loading—fetch only what the client asks for
- Separation of responsibilities—clean, maintainable code
- Natural support for nested/related data
Node.js Example with Apollo Server
We will build a tiny GraphQL API exposing User
and Address
types and use resolvers for the Query.user
and User.address
fields.
1) Setup
mkdir graphql-resolver-example
cd graphql-resolver-example
npm init -y
npm install apollo-server graphql
2) Schema and Resolvers (index.js)
Create index.js
with:
const { ApolloServer, gql } = require('apollo-server')
// In-memory data
const users = [
{ id: '1', name: 'John', age: 30, addressId: 'a1' },
{ id: '2', name: 'Maria', age: 28, addressId: 'a2' },
]
const addresses = [
{ id: 'a1', city: 'New York', state: 'NY' },
{ id: 'a2', city: 'San Francisco', state: 'CA' },
]
// GraphQL schema (SDL)
const typeDefs = gql`
type Address {
city: String!
state: String!
}
type User {
id: ID!
name: String!
age: Int!
address: Address!
}
type Query {
user(id: ID!): User
}
`
// Resolvers
const resolvers = {
Query: {
user: (_, { id }) => users.find((u) => u.id === id) || null,
},
User: {
// Field resolver: map user's addressId to an Address
address: (user) => addresses.find((a) => a.id === user.addressId),
},
}
const server = new ApolloServer({ typeDefs, resolvers })
server.listen({ port: 4000 }).then(({ url }) => {
console.log(`GraphQL server ready at ${url}`)
})
3) Run and Test
node index.js
Open the printed URL (for example, http://localhost:4000/
) and run:
query {
user(id: "1") {
name
age
address { city state }
}
}
Expected response:
{
"data": {
"user": {
"name": "John",
"age": 30,
"address": { "city": "New York", "state": "NY" }
}
}
}
Conclusion
Field resolvers power GraphQL’s flexibility. By defining resolvers per field—top‑level and nested—you get precise control over how data is fetched and shaped. This improves efficiency and code clarity, especially as schemas grow.