GraphQL vs REST API
GraphQL lets clients ask for exactly what they need. REST lets servers decide what clients get. Both sides think they are right.
REST API
REST is simpler, more cacheable, and better understood by every developer on earth. GraphQL solves real problems for companies with complex client needs (mobile + web + third parties), but for most teams, it adds complexity that never pays off. Pick REST unless you have a specific, painful problem that GraphQL uniquely solves.
The Hype Cycle Is Over
GraphQL launched from Facebook in 2015 and for about 5 years, the tech industry lost its collective mind. Every startup adopted it. Conference talks treated REST like a legacy technology.
Then reality set in. Teams discovered that GraphQL does not eliminate complexity — it moves it. Instead of overfetching on the server, you are now writing resolvers, managing schemas, handling N+1 queries, and explaining to your junior developer why their innocent-looking query just brought down the database.
REST is boring. Boring is underrated.
Where GraphQL Actually Shines
GraphQL solves one problem extremely well: when multiple clients with different data needs consume the same API.
Facebook built GraphQL because their mobile app, web app, and React Native app all needed different slices of the same data. A user profile on mobile shows 5 fields. On web, it shows 20. With REST, you either overfetch (send all 20 to mobile) or create separate endpoints for each client.
With GraphQL, each client queries exactly what it needs. This is genuinely powerful.
If you have one client (a web app) talking to one API, GraphQL is overhead with no benefit.
What Nobody Tells You
GraphQL caching is a nightmare. REST APIs cache trivially — HTTP caching, CDN caching, reverse proxy caching all work out of the box with GET requests. GraphQL uses POST for everything, which means your CDN is useless without specialized tooling.
Persisted queries help, but that is extra infrastructure you need to build and maintain.
N+1 queries will destroy your database. A nested GraphQL query like users { posts { comments { author } } } can generate hundreds of database queries. DataLoader solves this, but every team learns about DataLoader the hard way — after the production incident.
Security is harder. With REST, you can rate-limit per endpoint. With GraphQL, one endpoint serves everything, and a malicious query can request your entire database graph. Query depth limiting and complexity analysis are not optional — they are mandatory, and most tutorials skip them.
File uploads require multipart spec workarounds. Error handling is non-standard. Monitoring is harder because every request hits the same endpoint.
REST in 2026
REST has not stood still. Modern REST APIs with: - OpenAPI 3.1 specs get you auto-generated TypeScript clients (openapi-typescript) - JSON:API or sparse fieldsets solve overfetching without GraphQL - tRPC gives you end-to-end type safety without a schema language - HTTP/2 multiplexing makes multiple small requests nearly as efficient as one big GraphQL query
tRPC in particular has eaten GraphQL's lunch for TypeScript full-stack apps. You get type safety, autocompletion, and no schema to maintain. It is REST under the hood but with the DX that made GraphQL attractive.
Switching Costs
REST to GraphQL: Very high. You need to define your entire schema, write resolvers for every type, set up DataLoader, implement authentication middleware, add query complexity limits, set up persisted queries for caching, and retrain your team. Budget 1-3 months for a medium-sized API.
GraphQL to REST: Also high. You need to design endpoint structures, handle the cases where clients were querying different field sets, and rebuild client-side data fetching. But the result is simpler infrastructure.
The cheapest option: do not switch. If REST works, keep it. If GraphQL works, keep it.
When to Use What
Use GraphQL when: - Multiple clients (mobile, web, third-party) need different data shapes - You are Facebook-scale with dedicated API platform teams - Your API surface is genuinely complex (50+ entity types with deep relationships) - You have already hired people who know GraphQL
Use REST when: - One or two clients consume your API - You want HTTP caching to just work - Your team is small and cannot afford the operational overhead - You are building a public API (REST is universally understood) - You value simplicity and debuggability
Use tRPC when: - Full-stack TypeScript with a single client - You want type safety without the ceremony
Quick Comparison
| Factor | GraphQL | REST API |
|---|---|---|
| Learning Curve | Schema, resolvers, DataLoader | HTTP methods + URLs |
| Caching | Complex, needs tooling | HTTP caching built-in |
| Overfetching | Eliminated by design | Common without sparse fields |
| Multiple Clients | Excellent, one schema | Separate endpoints or BFF |
| Security | Query depth/complexity needed | Per-endpoint rate limiting |
| Tooling Maturity | Apollo, Relay, Hasura | Universal, decades of tooling |
| Type Safety | Schema-first, codegen | OpenAPI + codegen or tRPC |
| File Uploads | Hacky multipart spec | Native multipart/form-data |
The Verdict
Use GraphQL if: You serve multiple client platforms with genuinely different data needs, you have the team to handle the operational complexity, and you have already evaluated tRPC and decided it does not fit.
Use REST API if: You are building a straightforward API, you want caching to work without extra infrastructure, your team is small, or you are building a public API for third-party developers.
Consider: Before choosing GraphQL, try adding sparse fieldsets or BFF (Backend for Frontend) to your REST API. You might solve the problem without the complexity.
REST is simpler, more cacheable, and better understood by every developer on earth. GraphQL solves real problems for companies with complex client needs (mobile + web + third parties), but for most teams, it adds complexity that never pays off. Pick REST unless you have a specific, painful problem that GraphQL uniquely solves.
Related Comparisons
Disagree? nice@nicepick.dev