What are the differences between GraphQL and REST?
REST and GraphQL are both API paradigms, but they optimise for different constraints. The right choice depends on client diversity, data shape variability, team structure, and caching requirements.
**Data fetching model**: REST organises resources at fixed URLs; a client fetches `/users/1` and `/users/1/orders` in two round trips. GraphQL exposes a single endpoint where the client specifies exactly which fields it needs in one query, eliminating over-fetching (receiving unused fields) and under-fetching (needing multiple requests). This is the primary driver for GraphQL adoption in mobile clients where bandwidth and latency are constrained.
**Schema and type system**: GraphQL has a mandatory, strongly-typed schema (SDL) that serves as a contract between client and server. Introspection lets tooling auto-generate documentation, type-safe clients, and mocks. REST has no built-in schema standard, though OpenAPI/Swagger fills this gap. The GraphQL schema makes breaking changes visible immediately and enables powerful developer tooling (GraphiQL, code generators).
**Versioning**: REST APIs typically version via URL (`/v2/`) or headers. GraphQL avoids versioning by evolving the schema additively—new fields are added, old ones deprecated. This requires careful schema governance but eliminates the maintenance burden of parallel API versions.
**Caching**: REST maps naturally to HTTP caching—GET requests are cacheable by URL at CDN and browser layers with no extra work. GraphQL queries are typically POST requests to a single URL, which breaks HTTP caching. Per-query caching requires either query hashing, persisted queries, or application-layer caches (DataLoader, Redis). This is a meaningful operational complexity cost.
**N+1 problem**: GraphQL's flexible resolution model can trigger N+1 database queries (one query per list item for a nested field). The standard mitigation is the DataLoader pattern—batching and deduplicating resolver calls within a single request.
**When to choose each**: REST is simpler, benefits from HTTP caching natively, and is well-understood by every HTTP toolchain. Choose GraphQL when you have multiple clients (web, mobile, third-party) with divergent data requirements, or when reducing mobile round trips is a priority. Many organisations use REST for public APIs (cacheability, simplicity) and GraphQL for internal/BFF (Backend-for-Frontend) layers.
| Aspect | REST | GraphQL |
|---|---|---|
| Endpoint structure | Multiple resource URLs | Single /graphql endpoint |
| Data fetching | Fixed response shape | Client-specified fields |
| Over/under-fetching | Common without BFF layer | Eliminated by design |
| HTTP caching | Native GET caching at CDN | Requires persisted queries or app cache |
| Versioning | URL or header versioning | Schema evolution + deprecation |
| Type system | Optional (OpenAPI) | Mandatory SDL schema |
| N+1 queries | Rare (server controls shape) | Common without DataLoader |
Covers over/under-fetching, single vs. multiple endpoints, and the caching trade-off with a recommendation tied to use case.
Covers all major dimensions, explains DataLoader for N+1, discusses schema evolution vs. URL versioning, and gives concrete guidance on when each is appropriate.
Reading the answer is step one. Explaining it unprompted — under interview pressure — is what actually matters. Get AI-graded feedback on your answer with follow-up probes on your weak points.
Get Graded — Free Assessment