GraphQL
GraphQL is a query language and runtime for APIs that lets clients ask for exactly the data they need — no more, no less. It's especially strong for complex UIs where REST's overfetching and underfetching become painful.
The trade-off: GraphQL makes data access easier for clients but makes cost control and authorization harder for the server, unless you design for them from the start.
TL;DR
- Invest in schema design and resolver performance up front.
- The biggest foot-gun is the N+1 query problem — fix it with request-scoped batching.
- Prefer cursor pagination.
- Enforce object- and field-level authorization, plus query depth/complexity limits.
Quick Example
A client requests precisely the fields it needs, across a relationship, in one round trip:
Core Concepts
Schema-first
You define types and fields; clients query against them. The schema is the contract.
Nullability is part of the contract
⚠️ Marking too many fields non-null backfires: a single failed resolver can null out the entire parent object instead of just that field.
Operations
- Query — read
- Mutation — write
- Subscription — real-time stream (often over WebSockets)
Schema Design
Resolvers
Keep resolvers thin: validate input, enforce auth, and delegate business logic to services. Put authorization next to the data — if Project.members is admin-only, enforce that in the resolver or a shared policy layer, never by assuming "the UI won't ask."
Performance: the N+1 Problem
The classic GraphQL pitfall:
Fix it with request-scoped batching (the DataLoader pattern): collect the IDs requested during a tick, issue one query, then map results back.
Pagination
Prefer cursor-based pagination — it's stable under inserts and performs at scale:
Authorization & Cost Control
GraphQL makes it easy to expose data and to request expensive graphs, so pair the two concerns:
See API Security.
Caching
GraphQL doesn't get HTTP caching for free the way REST does:
GraphQL vs REST
See REST API Design.
Common Mistakes
No query depth or complexity limits
Authorization only at the top level
FAQ
What is the N+1 problem in GraphQL?
It's when resolving a list triggers one extra query per item (1 list query + N item queries). Request-scoped batching (DataLoader) collapses those N queries into one, which is the standard fix.
Is GraphQL more or less secure than REST?
Neither inherently — but GraphQL's flexibility means you must add field-level authorization and query cost limits that REST endpoints often get implicitly. Skipping those is the common source of GraphQL vulnerabilities.
Should I use GraphQL or REST?
Use GraphQL when diverse clients need flexible data shapes and you'll invest in schema governance. Use REST when resources map cleanly to endpoints and you want HTTP caching and simplicity.
How do I cache GraphQL responses?
Use persisted queries plus a CDN for GET requests, and request-scoped batching/caching on the server. Field-level caching is possible but requires careful invalidation.
Related Topics
- REST API Design — The alternative style
- API Security — Field-level authz and cost control
- API Documentation — Documenting the schema
- WebSockets — Transport for subscriptions
- Error Handling — The
errorsarray - REST vs GraphQL — When REST is the better choice