Mental model
REST organizes APIs around fixed resource URLs (/users/42/orders), while GraphQL provides a single POST endpoint (/graphql) accepting typed query documents so clients request exactly the fields they need.
Theory
- REST (Representational State Transfer): Standard HTTP verbs (
GET,POST,PUT,DELETE), URL-addressable resources, browser-cacheable GET responses. - GraphQL: Declarative schema definition language (
type Query,type Mutation). Solves over-fetching and under-fetching by letting clients query arbitrary nested graphs in a single request.
Alternatives and trade-offs
- REST APIs: Simple caching via standard HTTP headers (
ETag,Cache-Control); leads to over-fetching or multiple client round-trips. - GraphQL APIs: Single request fetches precise fields; complex query execution, requires DataLoader to avoid N+1 database query explosion, disables standard HTTP caching.
Failure modes and misconceptions
- Un-batched N+1 Resolvers: Resolving nested relations without DataLoader triggers 1 initial query followed by N individual database queries for child items (e.g. fetching 100 posts triggers 100 DB queries for author records).
- Un-restricted Query Depth: Allowing clients to execute arbitrarily nested recursive queries (
user { friends { friends { friends ... } } }) brings down server CPU/RAM. Always enforce maximum query depth limits.
Decision scenario
Implement DataLoader batching and query depth validation when building GraphQL APIs for complex client applications to prevent N+1 database query floods.
Learning outcomes
- Compare REST resource endpoints with GraphQL declarative queries.
- Resolve the N+1 database query problem using DataLoader batching.
- Implement query complexity limits to defend against deeply nested GraphQL queries.
Trade-offs
GraphQL eliminates client over-fetching and multi-roundtrip latency, but replaces HTTP URL caching with complex server-side query execution and batching requirements.