REST vs GraphQL — A Practical Comparison for Backend Developers

REST and GraphQL both let a client talk to a server over HTTP, but they solve the data-fetching problem very differently. Picking the wrong one for your use case leads to either a sprawling mess of endpoints or an over-engineered query layer nobody on the team fully understands. This guide breaks down the real trade-offs with examples so you can choose confidently.

Over-Fetching and Under-Fetching

REST endpoints return a fixed shape of data. If a mobile screen only needs a user's name and avatar, a REST /users/42 endpoint often returns the entire user object anyway — that is over-fetching. If the screen needs data from two resources, the client ends up calling two endpoints — that is under-fetching.

// REST: two round trips to build one screen
GET /users/42          -> { id, name, email, address, avatarUrl, createdAt, ... }
GET /users/42/orders   -> [{ id, total, status }, ...]

// GraphQL: one request, exact fields
query {
  user(id: 42) {
    name
    avatarUrl
    orders {
      id
      total
    }
  }
}

GraphQL lets the client specify exactly which fields it needs, in a single request, solving both problems at once.

Endpoint Design vs a Single Endpoint

REST APIs are organized around resources and URLs: /users, /users/42/orders, /products/9. Every new data need often means a new endpoint or a new query parameter. GraphQL exposes a single endpoint — typically POST /graphql — and the query itself describes the shape of data returned.

  • REST — many endpoints, each with a predictable, fixed response shape
  • GraphQL — one endpoint, flexible response shape driven by the query
  • REST — HTTP methods (GET, POST, PUT, DELETE) map naturally to CRUD actions
  • GraphQL — queries for reads, mutations for writes, subscriptions for real-time updates

Caching Trade-offs

This is where REST has a structural advantage. Because REST resources map to URLs, HTTP caching (browser cache, CDN, reverse proxies like Nginx or Varnish) works out of the box using standard headers.

# REST — trivially cacheable by URL
GET /products/9
Cache-Control: public, max-age=300
ETag: "a1b2c3"

# GraphQL — every query is POST /graphql with a body,
# so URL-based HTTP caching does not apply by default.
# Teams instead cache at the field/resolver level or use
# persisted queries with GET requests.

GraphQL can still be cached, but it requires extra tooling — persisted queries, normalized client-side caches (like Apollo Client or Relay), or response-level caching with tools like GraphQL CDN gateways.

Errors and Status Codes

REST uses HTTP status codes to communicate success or failure (200, 201, 400, 404, 500), which plays nicely with existing HTTP tooling, logging, and monitoring. GraphQL almost always returns 200 OK even when a query partially fails, embedding errors inside the response body instead.

// GraphQL error response — still HTTP 200
{
  "data": { "user": null },
  "errors": [
    { "message": "User not found", "path": ["user"] }
  ]
}

This means REST-style monitoring based on status codes (like alerting on 5xx rates) does not directly work for GraphQL — you need to inspect the errors array instead.

When to Choose Which

  • Choose REST — public APIs, simple CRUD services, when HTTP caching matters, small teams, third-party integrations that expect standard REST
  • Choose GraphQL — multiple client types (web, iOS, Android) with different data needs, complex nested/relational data, rapidly evolving frontend requirements
  • Choose REST — file uploads and streaming, where REST's native HTTP semantics are simpler
  • Choose GraphQL — you want strong typing and self-documenting schemas via introspection

Frequently Asked Questions

Is GraphQL faster than REST?

Not inherently. GraphQL can be faster over the wire because it avoids over-fetching, but a single GraphQL query can trigger many resolver calls on the backend, which sometimes makes it slower than a well-indexed REST endpoint if not optimized with techniques like DataLoader.

Should a new project use REST or GraphQL?

Use REST for simple CRUD APIs, public APIs that need easy caching, and small teams. Use GraphQL when you have many different clients (web, mobile, third-party) with very different data needs from the same backend.

Can REST and GraphQL be used together?

Yes. Many teams expose a GraphQL layer on top of existing REST services, or keep REST for simple internal endpoints while using GraphQL for the public-facing aggregation layer that combines multiple services.

Debug Errors Faster with AI

Whether you're debugging a REST 500 or a GraphQL resolver error, paste the message into our free AI Error Explainer to get a plain-English cause and fix.

Related articles