Few engineering debates generate more heat than GraphQL vs REST. Both camps have legitimate arguments. Both have real-world success stories at massive scale. The framing of the question as "which is better?" is the wrong one — the right question is "which is better for this specific use case?"
REST: Why It's Still the Right Default
REST's strength is its simplicity and ubiquity. Every HTTP client in every language can consume a REST API without a specialised library. Caching at the CDN layer is trivial — a GET to /products/123 can be cached globally with standard HTTP headers. Browser DevTools, curl, Postman — all work natively. For public APIs consumed by third parties you don't control, REST is still the only sensible choice.
The genuine problem REST has is over-fetching and under-fetching. A mobile client displaying a user card might need name, avatar, and follower count — but the /users/:id endpoint returns 40 fields. Multiple endpoints mean multiple round trips. For teams with a single, controlled frontend, this is manageable. For teams with many frontends (iOS, Android, web, partner integrations) needing different data shapes from the same resources, REST's rigidity becomes expensive to maintain.
GraphQL: Where It Genuinely Shines
GraphQL's type system and query language eliminate over/under-fetching entirely — clients request exactly the fields they need. A single GraphQL endpoint replaces dozens of REST routes. Schema introspection enables excellent developer tooling (GraphiQL, Apollo Studio) and auto-generated documentation. For complex, highly relational data — think social graphs, content management, e-commerce catalogs — GraphQL produces dramatically cleaner client code.
The costs are real: no native HTTP caching (requires persisted queries or a CDN with query-aware caching), N+1 query problems require DataLoader to solve, schema design requires significant upfront thought, and the learning curve for REST-trained developers is non-trivial.
Our Decision Framework
- Public / partner API: REST always. Third parties expect it.
- Internal API with one frontend: REST with BFF pattern.
- Internal API with 3+ frontends needing different data shapes: GraphQL.
- Highly relational data, complex filtering: GraphQL.
- Simple CRUD operations, file uploads, webhooks: REST.