GraphQL vs REST
GraphQL vs REST: when each wins, when the trade-offs bite, and how teams pick by question, not by ideology.
GraphQL vs REST
EXAMPLE
# ===== TL;DR ===== # REST Resources at URLs; HTTP verbs as operations; one shape per endpoint. # GraphQL Type graph at one endpoint; clients pick fields; queries / mutations / subs. # Both are 'fine' for most apps. The right call depends on consumers + team. # ===== Where GraphQL wins ===== # 1. Many client shapes # Web + mobile + partner integration need different views of the same data. # GraphQL lets each ask for what it needs. # 2. Aggregation # A single page joins data from 5 services. REST needs 5 round trips OR a backend-for-frontend. # 3. Strong typing across boundaries # The schema is the contract; codegen produces typed clients. # 4. Self-documenting # GraphiQL / Apollo Studio explorers > paginated swagger docs. # ===== Where REST wins ===== # 1. Simple CRUD # One client + one resource model + standard HTTP caching = less ceremony. # 2. Caching # HTTP cache (Cache-Control, CDN, ETag) just works. GraphQL needs client cache work. # 3. File uploads / downloads # HTTP semantics fit naturally. # 4. Tooling expectations # Postman + curl + browser address bar are first-class. # ===== Areas where neither owns ===== # Pagination: REST has many styles (offset, cursor); GraphQL has Relay-style cursors # Auth: Identical concerns (tokens, scopes); not a tie-breaker # Versioning: REST does /v1/, GraphQL evolves the schema (add fields, deprecate) # DDoS / abuse: Both need limits; GraphQL needs depth + complexity gates too # ===== Common GraphQL costs ===== # - N+1 problem (every list field can hit the DB once per item; DataLoader fixes) # - Caching needs client work (Apollo / urql cache by type + id) # - Schema design is a real upfront skill # - Query complexity attacks on public APIs (limit + persisted queries) # ===== Common REST costs ===== # - Over-fetching: endpoint returns more than the client needs # - Under-fetching: client must call N endpoints to render one screen # - Versioning by URL: /v1, /v2 paths multiply # - Inconsistent error shapes across endpoints # ===== Hybrid is common ===== # - GraphQL gateway for read-heavy aggregation # - REST for writes + file uploads + webhooks # - Or REST as the primary; GraphQL as an internal BFF for a complex client # ===== When NOT to choose GraphQL ===== # - One team, one client, one DB, simple CRUD # - Tight launch deadline + no GraphQL experience # - Public API where caching matters more than flexibility (REST + ETag is hard to beat) # ===== Quick smell test ===== # 'Could I shape the perfect REST API for this client today?' # Yes -> REST is probably fine. # No (because clients differ) -> GraphQL earns its complexity. # ===== Patterns to internalise ===== # - Pick on consumers + team, not on hype # - Pair GraphQL with persisted queries + DataLoader + complexity limits # - REST with proper Cache-Control + ETag is incredibly fast # - Document the schema (REST: OpenAPI; GraphQL: schema introspection) # ===== Pitfalls ===== # - GraphQL because it is 'modern' — without N+1 mitigation it is slow # - REST without a style guide -> inconsistent across teams # - Treating GraphQL as REST with extra steps # - Skipping query limits on a public GraphQL API
Why it matters
Choose the API style for your consumers, not for the framework. GraphQL for many clients with different shapes and heavy aggregation; REST for caching, simple CRUD, and predictable HTTP semantics. Hybrids are common and pragmatic. The wrong choice mostly costs developer time, not user time.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
# REST: GET /users/1 then GET /users/1/posts # GraphQL: one query returns both in one round-trip.Try it Yourself »
Discussion
Loading…