Articles

REST vs GraphQL: Choosing an API Style

REST exposes fixed endpoints per resource; GraphQL lets clients query exactly the fields they need through one endpoint. How to choose between them.

Takina Takina · · 4 min read
A code editor showing componentized source files

REST structures an API around fixed endpoints that each represent a resource, returning a predetermined shape of data for every request to that endpoint. GraphQL instead exposes a single endpoint backed by a schema, letting each client specify exactly which fields it wants in a query. Both are ways of designing the contract between a client and a server — the difference is who decides what shape a response takes: the server, in REST’s case, or the client, in GraphQL’s.

How REST works

A REST API organizes functionality around resources, each addressed by a URL, with the HTTP verb (GET, POST, PUT, DELETE) describing the action:

GET    /users/42
GET    /users/42/posts
POST   /users/42/posts
DELETE /posts/107

Each endpoint returns a fixed shape — hitting /users/42 typically returns the full user object, whatever fields that includes, whether or not the client needs all of them. This is simple and predictable: the response for a given endpoint rarely surprises you, and REST maps naturally onto HTTP caching, since GET requests to the same URL can be cached by intermediaries like a CDN without any special handling.

How GraphQL works

GraphQL exposes one endpoint (commonly /graphql) and lets the client send a query describing exactly the fields it wants, across potentially multiple related resources, in a single request:

query {
  user(id: 42) {
    name
    posts(limit: 3) {
      title
      publishedAt
    }
  }
}

The server resolves that query against a strongly typed schema and returns exactly the requested shape — no more, no less. A single request can pull data that would otherwise require several REST calls (the user, then separately their posts), which is GraphQL’s signature advantage: it collapses what REST calls “N+1 requests” into one round trip.

The core trade-off

The difference boils down to who controls the response shape.

With REST, the server decides. Every consumer of /users/42 gets the same fields, whether they’re a mobile app that only needs a name and avatar, or an admin dashboard that needs everything. This tends to produce either over-fetching (getting fields you don’t need) or under-fetching (needing a second request for related data), and API teams often respond by adding new endpoints or query parameters to cover each new client’s needs — which grows the surface area over time.

With GraphQL, the client decides. Each consumer asks for precisely what it needs, which eliminates over- and under-fetching by construction. The trade-off is that the server has to do more work per request — resolving an arbitrary combination of fields instead of returning one fixed payload — and that flexibility makes caching much harder, since two clients rarely send identical queries the way they’d hit identical REST URLs.

REST vs GraphQL

RESTGraphQL
EndpointsMany, one per resourceSingle endpoint
Response shapeFixed by the serverChosen by the client, per query
Over/under-fetchingCommonEliminated by design
HTTP cachingNative, via URLsRequires custom caching layers
Related dataOften needs multiple requestsUsually one request
SchemaOptional (often OpenAPI as a separate spec)Built in, strongly typed, self-documenting
Learning curveLower, maps to familiar HTTP verbsHigher, requires learning the query language
Tooling maturityExtremely broad and matureStrong but narrower

Where each one wins

REST tends to be the better default for public APIs, simple CRUD services, and anything that benefits from HTTP’s native caching and the enormous ecosystem of tooling built around it — proxies, gateways, monitoring, and client libraries that all assume URL-per-resource semantics. It’s also just simpler to reason about for small APIs: there’s no query language to learn, and curl-ing an endpoint is enough to understand what it returns.

GraphQL tends to win in applications with many different client types (web, mobile, various dashboards) pulling overlapping-but-different slices of a large, deeply related data graph. It shines when a product team doesn’t want backend engineers to become a bottleneck for every new field a frontend needs — the frontend can query for the exact shape it wants without a backend change. It also earns its keep when reducing round trips genuinely matters, such as a mobile client on a slow connection that would otherwise need several sequential REST calls.

Not mutually exclusive

Plenty of real systems use both. A public-facing REST API might sit alongside an internal GraphQL layer used only by the product’s own frontends, or a GraphQL gateway might sit in front of several existing REST services, aggregating them into one queryable graph without requiring a rewrite of the underlying services. Choosing between them isn’t necessarily an all-or-nothing decision for an entire organization — it’s a decision you can make per API, based on who’s consuming it and how varied their data needs are.

It’s also worth knowing that neither is the only alternative: gRPC targets a different problem entirely — fast, strongly-typed service-to-service communication rather than flexible client-facing queries — and is common inside backend systems even when the public-facing API is REST or GraphQL.

The takeaway

REST organizes an API around fixed, server-defined endpoints, trading flexibility for simplicity and native HTTP caching. GraphQL organizes an API around a single, client-queried schema, trading server complexity and harder caching for precise, over-fetch-free responses. Reach for REST when you want simplicity, broad tooling, and cacheable resources; reach for GraphQL when multiple clients need different slices of deeply related data and round trips are expensive. Many systems end up using both, applied where each fits best.

Chisato Chisato · · 4 min read

gRPC vs REST: Choosing an API Style

gRPC uses binary Protocol Buffers over HTTP/2 for fast, typed service calls; REST uses JSON over HTTP for accessible, resource-based APIs. How to pick.

#API #Web Development #Backend
Takina Takina · · 4 min read

What Is the Backend-for-Frontend (BFF) Pattern?

A backend-for-frontend (BFF) is a dedicated backend layer for one client type — shaping, aggregating, and simplifying calls to shared downstream APIs.

#Backend #Web Development #Architecture
The Lycoris Team The Lycoris Team · · 4 min read

API Versioning Strategies Explained

URI paths, custom headers, and content negotiation are the three common ways to version an API. Tradeoffs of each, and how to avoid breaking clients.

#Web Development #Developer Tools #Backend