REST vs GraphQL: which API style should you choose?
REST and GraphQL are two ways to build web APIs. REST uses fixed endpoints and HTTP methods; GraphQL uses a single endpoint where clients query exactly the fields they need. Compare the trade-offs and learn how to choose.
On this page
REST and GraphQL are the two dominant styles for building web APIs, and they answer the same question — how should a client get data from a server? — in very different ways. REST exposes a set of fixed endpoints, one per resource, that you call with HTTP methods like GET, POST, PUT, and DELETE. GraphQL exposes a single endpoint where the client sends a query describing exactly the fields it wants and gets back a JSON result that mirrors that query. Neither is universally better: each fits different teams, workloads, and client shapes. This guide compares them across the trade-offs that actually matter and gives you a decision path.
What REST is
REST (Representational State Transfer) is an architectural style introduced by Roy Fielding in his doctoral dissertation in 2000, built around the constraints that shaped the World Wide Web. An application that adheres to its constraints is called RESTful. In practice, when developers say "REST API," they usually mean an HTTP-based API organized around resources: each thing your system manages (users, orders, products) gets one or more URLs, and you act on it with HTTP methods.
The core idea is the uniform interface: your API exposes a stable set of resources identified by URLs, clients interact with them through standardized HTTP verbs, and responses contain representations of those resources.
The HTTP methods a REST API uses have well-defined semantics:
- GET requests a representation of the specified resource and should only retrieve data.
- POST submits an entity, often changing state or causing side effects.
- PUT replaces the target resource with the request content.
- PATCH applies partial modifications to a resource.
- DELETE deletes the specified resource.
These methods also have guarantees that matter for clients. GET, HEAD, and OPTIONS are safe (they do not change server state) and GET and HEAD are cacheable. PUT and DELETE are idempotent (repeating them has the same effect as doing them once). Understanding these properties is part of what makes a REST API predictable and cacheable at every layer, from the browser to a CDN.
What GraphQL is
GraphQL is a query language and runtime developed at Facebook, released as an open-source specification in 2015, and moved to the GraphQL Foundation under the Linux Foundation in 2018. Instead of many fixed endpoints, a GraphQL API exposes one endpoint and a typed schema. The schema describes every type and field the API can return, and clients send queries that ask for exactly the data they need.
A GraphQL query mirrors the shape of the result. If a client wants a user's name and only their latest posts, it writes that shape directly in the query, and the server returns JSON that follows it. The client drives the response; the server does not decide which fields to include. This fixes two problems common in REST:
- Over-fetching — a REST endpoint returns everything on a resource even when the client needs one field.
- Under-fetching — a REST client must make several requests (one per resource) or be given a bespoke endpoint to assemble a single view.
GraphQL supports reading data (queries), changing data (mutations), and real-time updates (subscriptions, often built on WebSockets). It is statically typed: the schema is the contract between client and server, and clients can validate queries against it before they run.
The key differences
| Aspect | REST | GraphQL |
|---|---|---|
| Endpoints | Many — one (or more) per resource | One endpoint for everything |
| How you request data | Fixed response per URL; HTTP methods select the action | Client writes a query for exactly the fields it needs |
| Data shape | Server decides; may over- or under-fetch | Client decides; result mirrors the query |
| Contract | URLs + HTTP methods + media types | Typed schema (single source of truth) |
| Caching | Great — HTTP caching works across all layers (CDN, browser) | Harder; usually need a GraphQL-specific cache |
| Versioning | Common approach is /v1, /v2 paths |
Schema evolves; fields can be added or deprecated |
| File uploads | Standard (multipart) | Needs extensions or workarounds |
| Tooling | Mature across every language | Strong client-side tools (Apollo, Relay, GraphiQL) |
When REST is the better choice
REST shines when its strengths map cleanly to your situation:
- Simple, resource-shaped APIs — if your data maps naturally to a handful of resources and clients mostly fetch whole objects, REST is uncomplicated and boring in the best way.
- Heavy caching and CDN use — because GET is cacheable and responses are per-URL, you can cache aggressively at the CDN, the proxy, and the browser, which is powerful for public, read-heavy content.
- Public APIs with unknown clients — the HTTP semantics (safe, idempotent, status codes) are well understood by every client and tool, and web infrastructure works with them out of the box.
- File uploads and simple integrations — multipart uploads, webhooks, and browser-native forms all work with REST without extensions.
- Long-lived, high-traffic services — a simple, stable REST surface is easy to cache and cheap to operate.
Many teams never outgrow REST. If your API has a few resources, consistent shapes, and modest client requirements, REST gives you caching, tooling, and simplicity for free.
When GraphQL is the better choice
GraphQL earns its complexity when REST's fixed shapes become the bottleneck:
- Many different clients, very different data needs — a mobile app wants small, specific payloads; a dashboard wants wide ones. GraphQL lets each client fetch exactly what it needs from one endpoint.
- Client-driven, nested data — when a view needs a user, their posts, and the comments on those posts, GraphQL assembles the whole graph in one query instead of making several round-trips.
- Rapidly evolving product — adding and deprecating fields in the schema is safer than contract changes across many endpoints.
- Strong typed contract as a team tool — one schema doubles as documentation, and clients can validate queries before they run.
- Multiple back-end services behind one API — resolvers can aggregate data from different sources and present it as a unified graph.
GraphQL makes the most sense when you control both client and server, clients actively, and the data shape is graph-like — which is exactly the situation where REST APIs tend to grow a pile of bespoke, one-off endpoints.
The honest downsides
Both styles have real costs, and choosing well means seeing the other side.
GraphQL is harder to cache. Because every query is different and all requests hit one endpoint, HTTP and CDN caching that works trivially for REST does not directly apply. Teams often add a caching layer (like Apollo or a CDN edge cache designed for GraphQL) and must think about per-query caching and the N+1 problem — where resolving a list triggers one query per item unless you batch and deduplicate with a data loader. A carelessly built GraphQL server can also produce heavier queries than intended, so query complexity limits and timeouts matter.
REST's weaknesses are the flip side of its simplicity. Clients are at the mercy of the server's chosen shapes: you over-fetch or under-fetch unless you create custom endpoints. Nested data often means several round-trips. Versioning is usually path-based, which leaves old endpoints around. And when different clients need very different views of the same resources, REST surfaces tend to drift from "one clean endpoint per resource" toward a graveyard of special-purpose endpoints.
How to decide
There is no universal winner — it depends on your clients, your team, and your operationally practical realities:
- Pick REST when you have a public or simple API, heavy read traffic, need CDN/browser caching, process file uploads, or value boring predictability.
- Pick GraphQL when you control the clients, they have diverse and nested data needs, your product evolves quickly, and you can invest in tooling and caching up front.
- Both can coexist — many teams run a REST API for public, cacheable read paths and a thin GraphQL layer for rich internal clients.
If you are unsure, start simple. REST is the safer default for most new APIs; adopt GraphQL when specific, repeated pain — over-fetching, many round-trips, or a broad multi-client product — makes the investment clearly worth it. The wrong choice is rarely permanent: the two styles can live side by side and you can migrate gradually.
FAQ
Is GraphQL a replacement for REST?
GraphQL is an alternative way to expose an API, not a drop-in replacement that is always better. It removes fixed per-resource endpoints and lets clients query exactly what they need from one typed endpoint. For many use cases REST is still a simpler and better-cached choice; for others GraphQL fixes real pain. Both can serve the same backend.
Can you use GraphQL and REST together?
Yes, and many teams do. A common pattern is keeping a REST API for public, cacheable, or simple read paths and adding a GraphQL layer for rich internal clients, or exposing both against the same data. They are not mutually exclusive, and you can migrate a service gradually rather than rewriting it.
Does GraphQL use HTTP?
GraphQL conventionally runs over HTTP with a single endpoint, usually accepting POST requests carrying the query, and it returns JSON. Under the hood it still uses HTTP, but it does not reuse standard HTTP caching and the per-resource URL semantics the way REST does, which is one reason caching is handled differently.
Which is faster: REST or GraphQL?
There is no inherent speed advantage — both run over HTTP. The practical difference is in the number of round-trips and the amount of data transferred. GraphQL can reduce both for nested, client-specific views. REST wins where HTTP caching means far fewer requests actually reach the server. Latency depends more on your server and caching than on the style itself.
Verdict
REST and GraphQL solve the same problem with opposite trade-offs, and the right answer depends on where you feel the pain. Choose REST when you want simple, resource-based endpoints plus free CDN and browser caching — the sensible default for most public and read-heavy APIs. Choose GraphQL when you control the clients, they need diverse and nested data, and the product evolves quickly enough that fixed shapes hurt. Start simple, adopt GraphQL deliberately when a concrete problem demands it, and remember the two styles coexist: you are not locked into one forever.
Sources
- Wikipedia — REST (en.wikipedia.org/wiki/Representational_state_transfer
- CC BY-SA)
- Wikipedia — GraphQL (en.wikipedia.org/wiki/GraphQL
- CC BY-SA)
- graphql.org — Learn / Best Practices (graphql.org/learn
- open-license)
- MDN — HTTP request methods (developer.mozilla.org/en-US/docs/Web/HTTP/Methods
- CC-BY-SA 2.5+)
Share this guide
Related guides
- What is GraphQL? How it works and when you should use it
GraphQL is an open-source query language for APIs that lets clients request exactly the data they need. This guide explains how GraphQL works, its type system, queries and mutations, and how it compares to REST.
- GraphQL vs gRPC: which API technology should you choose?
GraphQL and gRPC are two modern ways to build APIs. GraphQL lets clients query exactly the fields they need over a single HTTP endpoint; gRPC calls typed remote methods over HTTP/2 with binary Protocol Buffers. Compare the trade-offs and learn when to choose each.
- REST vs gRPC: which API style should you choose?
REST and gRPC are two ways to build APIs. REST uses HTTP and JSON with universal browser support; gRPC uses HTTP/2 and Protocol Buffers for binary efficiency and code-generated stubs. Compare the trade-offs and learn when to choose each.