Skip to content
Sahil Durgia/ full-stack
2 min readFull-Stack & AI

REST vs GraphQL: Choosing the Right API Style for a Real Project

REST has a real limitation with nested data. GraphQL fixes that, at a real cost — not a strictly better technology, a different tradeoff entirely.

GraphQLRESTAPI design

The REST APIs post in the web fundamentals series flagged this as its own topic — worth the full comparison, because the actual tradeoff is more specific than "GraphQL is more modern."

The specific problem GraphQL solves

REST, fetching a user + their orders + each order's items:
GET /users/42          → user
GET /users/42/orders    → orders (N+1 round trips already starting)
GET /orders/101/items   → items for order 101
GET /orders/102/items   → items for order 102
...

GraphQL, the same data, one round trip:
query {
  user(id: 42) { name, orders { id, items { name, price } } }
}

REST's resource-per-URL model means a nested object graph either needs multiple round-trips (as above) or a custom endpoint built specifically for this one screen's exact data shape — neither scales cleanly as an app's screens multiply, each with a slightly different nested-data need. GraphQL lets the client specify exactly the shape it needs, resolved server-side in one request, no matter how nested.

What REST has that GraphQL structurally gives up

REST's GET responses are cacheable at the HTTP level, by the browser, a CDN, or an intermediate proxy, for free — because a GET to a specific URL is a well-defined, cacheable operation by the HTTP spec covered earlier in this blog. GraphQL typically uses a single POST endpoint for every query, which HTTP-level caching doesn't apply to in the same way — GraphQL clients solve caching themselves, client-side (as one specific example, Apollo Client's normalized cache), which is real, working, but is application-level caching you now own, not free infrastructure-level caching you get by default.

The honest decision framework

Nested, client-driven data requirements that vary a lot screen to screen (a complex dashboard, a mobile app hitting the same backend as a web app with different data needs per platform) genuinely favor GraphQL. A simpler API surface, a small team, or a strong need for HTTP-level caching genuinely favors REST. Most projects — this site's own contact-form API route included — never actually reach the complexity where REST's limitation becomes a real, felt problem, which is exactly why REST remains the sensible default until a project's actual data-shape needs prove otherwise.

Keep reading
Next: authentication, explained

Part 5 of the full-stack & AI series.