Overview
REST is an architectural style built on HTTP itself: resources live at URLs, and the HTTP verb
(GET/POST/PUT/DELETE) says what you're doing to them. GraphQL is a query language and
runtime that exposes a single endpoint and a typed schema, and lets the client describe exactly
which fields it wants back in one request.
A request, side by side
A REST client fetching a user and their five most recent posts typically needs two round trips (or a bespoke endpoint that combines them):
GET /users/42
GET /users/42/posts?limit=5The equivalent GraphQL request is one round trip, and it asks for exactly the fields it needs, no more, no less:
query {
user(id: 42) {
name
posts(limit: 5) {
title
publishedAt
}
}
}Feature comparison
| REST | GraphQL | |
|---|---|---|
| Endpoints | Many, one per resource | One |
| Over/under-fetching | Common, fixed response shape per endpoint | Avoided, client picks fields |
| Caching | Native HTTP caching (GET, ETags, CDNs) | Needs a client-side normalized cache (Apollo, urql) or persisted queries |
| Versioning | URL or header versioning (/v2/users) | Schema evolves in place, deprecate fields instead of versioning |
| Type safety | Only what you enforce yourself (OpenAPI is optional) | Built in; the schema is the contract |
| Tooling maturity | Extremely mature, ecosystem-wide | Mature, but younger and more opinionated |
| Server complexity | Low, routes map to handlers | Higher, resolvers, and the N+1 query problem needs a dataloader pattern |
| Real-time | Requires a separate mechanism (WebSockets, SSE) | Subscriptions are part of the spec |
Where REST tends to win
Public APIs that want to lean on HTTP's existing infrastructure, caching proxies, CDNs, rate limiters, and API gateways all already understand REST semantics for free. It's also simpler to reason about and operate when your resources map cleanly to CRUD, and it doesn't require every client to understand a schema before making a request.
Where GraphQL tends to win
Products with many different clients (web, iOS, Android, third-party integrations) that each want a different shape of the same underlying data, mobile wants a lean payload, a dashboard wants a rich one, and GraphQL lets each ask for exactly what it needs from the same backend without either over-fetching or requiring N bespoke endpoints.
Warning
GraphQL doesn't remove the need for backend discipline, a naive resolver for posts on every user
in a list can turn one request into an N+1 query storm. That's a real operational cost REST's
per-endpoint model doesn't have by default.
Verdict
REST and GraphQL solve overlapping but different problems: REST leans on HTTP's own caching and tooling and stays simple for CRUD-shaped APIs; GraphQL trades server-side complexity for precise, client-driven data fetching across many consumers. Many real systems use both, REST (or plain HTTP) for simple public endpoints and file/webhook delivery, GraphQL for a product's primary data-fetching layer.