Module P-11·27 min read

Schema definition language, queries/mutations/subscriptions, resolvers, the N+1 problem and DataLoader, auth in GraphQL — and when to choose GraphQL over REST.

Module P-11 — GraphQL with Apollo Server

What this module covers: REST and GraphQL solve the same problem — exposing data over HTTP — with different trade-offs. GraphQL gives clients precise control over what data they receive, eliminates over-fetching and under-fetching, and makes schema changes visible and versioned. This module covers the Schema Definition Language, building a GraphQL API with Apollo Server and Express, writing resolvers for queries and mutations, implementing subscriptions for real-time data, solving the N+1 problem with DataLoader, adding authentication, and knowing when to reach for GraphQL instead of REST.


REST vs GraphQL: The Core Trade-Off

Consider a mobile screen showing a user's profile with their five most recent posts and follower count.

REST approach — three requests:

text

Problems:

  • Three round-trips (three network waterfalls on mobile)
  • /users/42 returns 20 fields; the screen needs 4
  • You're either over-fetching (wasting bandwidth) or under-fetching (needing more calls)
  • Adding a new screen requirement changes which endpoints you need to call

GraphQL approach — one request, exactly the data needed:

graphql

One request, four fields from user, three fields per post. The client defines the shape. Adding a new screen just changes the query.

GraphQL shines when: you have multiple clients with different data needs (web, mobile, partner integrations), your data is deeply relational, or your API is consumed by teams you don't control.

REST shines when: you have a simple CRUD API, need HTTP caching, are building a public API that tools should be able to discover automatically, or your team knows REST well.


Setup: Apollo Server with Express

bash
typescript

Context: Authentication in GraphQL

GraphQL doesn't have middleware like Express. Authentication goes into the context function — called once per request and passed to every resolver:

typescript

Resolvers

Resolvers are functions that return the data for each field. They receive (parent, args, context, info):

typescript
typescript

Type resolvers — resolve fields that need additional data fetching:

typescript

The N+1 Problem and DataLoader

The most common GraphQL performance bug. A query for 20 posts with their authors:

graphql

The Post.author resolver runs 20 times, each doing SELECT * FROM users WHERE id = ?. That's 21 queries total (1 for posts + 20 for authors).

DataLoader batches and caches these lookups:

bash
typescript

Add loaders to context:

typescript

Use loaders in resolvers:

typescript

Now the same query for 20 posts produces just 2 queries: one for posts, one SELECT WHERE id IN (1, 5, 7, ...) for all authors. DataLoader collected all the load() calls in a tick, batched them, and resolved them together.


Subscriptions with WebSocket

GraphQL subscriptions deliver real-time updates over WebSocket:

bash
typescript

For production, replace graphql-subscriptions PubSub (in-memory, single server) with graphql-redis-subscriptions (Redis-backed, multi-server).


Wiring Apollo Server to Express

typescript
typescript

Open http://localhost:3000/graphql — Apollo Studio Sandbox provides an in-browser IDE for exploring the schema and sending queries.


GraphQL Error Handling

typescript

GraphQL always returns 200 OK — errors are in the errors array of the response body. The extensions.code is the convention for programmatic error handling by clients.


When to Choose GraphQL vs REST

Choose GraphQL when:

  • Multiple clients (web, mobile, partner) need different data shapes from the same API
  • Data is highly relational (users → posts → comments → likes → users…)
  • You want self-documenting APIs — the schema IS the documentation
  • Your frontend team wants to move fast without waiting for backend changes
  • Rapid iteration on new screens/features

Choose REST when:

  • Simple CRUD operations with predictable resource shapes
  • You need HTTP-level caching (CDN caching of GET responses)
  • Building a public API that must be discoverable by generic tools
  • File uploads are a primary concern (GraphQL handles these awkwardly)
  • Your team knows REST deeply and the API is not complex

Mixing both is valid. Many large companies run REST for public APIs (stable, cacheable, simple) and GraphQL for internal front-end APIs (flexible, fast to iterate). Your Node.js app can serve both on the same server.


Summary

  • GraphQL solves over-fetching and under-fetching — clients request exactly the fields they need in a single round-trip. REST solves discoverability, caching, and simplicity.
  • Schema Definition Language is the contract. Define types, queries, mutations, and subscriptions before writing a single resolver.
  • Context function runs once per request — the right place to verify tokens and attach user data for all resolvers.
  • DataLoader is non-negotiable. Any Post.author resolver that queries the DB directly will produce N+1 queries. Batch all related-entity lookups.
  • Subscriptions use WebSocket under the hood. graphql-ws is the current standard. Replace in-memory PubSub with Redis-backed PubSub for multi-server deployments.
  • GraphQL errors return 200 with an errors array. Use extensions.code for programmatic handling. Never expose internal error details in production.

Next: background jobs with BullMQ — deferring slow work off the request path, retries with exponential backoff, scheduled jobs, job priorities, and concurrency control.


Knowledge Check

In the context of GraphQL, what problem does DataLoader primarily solve?


In an Apollo Server Express setup, where is the most appropriate place to perform authentication (e.g., verifying a JWT) so that the user's information is available to all resolvers?


How does error handling in a standard GraphQL API typically differ from a REST API?

Test your knowledge with more question sets

Sign in to access a wider variety of questions and get notified when new practice sets are added to this module.

Sign in & Register

Discussion

0

Join the discussion

Loading comments...

© 2026 Jatin Jain Saraf (JJS). All rights reserved.