Quick answer: REST exposes your data as a set of resources at fixed URLs, and the server decides what each response contains. GraphQL exposes a single endpoint and a typed schema, and the client asks for exactly the fields it needs in one query. REST is the safer default for public APIs, simple data and anything that benefits from HTTP caching. GraphQL is worth a serious look when you have several client apps, deeply related data and lots of round trips, but it is young, the tooling is thin outside JavaScript, and it asks more of your team.
When Facebook released GraphQL as an open source project in September last year, along with a specification and a reference implementation in JavaScript, it caught the attention of a lot of developers who were tired of juggling dozens of REST endpoints for one mobile screen. Facebook had been using it internally since 2012 to power its mobile apps. Since then, the question we hear is simple: should our next API be GraphQL or REST? This article sets out the differences and gives a practical way to decide.
A quick refresher on REST
REST is an architectural style built on top of HTTP. Data is organised as resources, each with its own URL, and you use standard HTTP methods to work with them:
GET /customers/42returns customer 42GET /customers/42/ordersreturns that customer’s ordersPOST /orderscreates an orderPUTorPATCH /orders/7updates an orderDELETE /orders/7removes it
The server decides the shape of each response. Status codes, headers and caching all follow HTTP rules that browsers, proxies and CDNs already understand. If you want a deeper look at good practice, our guide to REST API design covers naming, versioning and error handling.
What GraphQL does differently
GraphQL is a query language for APIs and a runtime for answering those queries. Instead of many URLs, there is usually one endpoint, often /graphql. The server publishes a schema that describes every type of object and how they connect. The client sends a query that names the fields it wants:
{
customer(id: 42) {
name
email
orders(last: 3) {
id
total
status
}
}
}
The response comes back as JSON in the same shape as the query, with only those fields. Changes to data are handled by “mutations”, which are defined in the schema just like queries.
Key parts of the GraphQL ecosystem today:
- The specification, published by Facebook as a working draft.
- graphql-js, the reference implementation in JavaScript.
- express-graphql, which adds a GraphQL endpoint to a Node.js Express server.
- GraphiQL, an in-browser tool for exploring a schema and writing queries.
- Relay, Facebook’s framework for connecting React apps to a GraphQL server.
Community implementations exist for Ruby, Python, PHP, Scala, .NET and others, at varying levels of maturity.
The main differences side by side
Fetching data
With REST, building one screen can take several requests: the customer, then their orders, then the products in each order. Each response may also include fields the screen does not need. These problems are often called under-fetching and over-fetching.
With GraphQL, the client gets everything for that screen in one request, with no extra fields. On mobile connections, where each round trip is slow, this can make a real difference.
Endpoints and versioning
REST APIs grow by adding endpoints, and breaking changes are often handled with versions such as /v1/ and /v2/. Custom endpoints for particular screens tend to pile up.
GraphQL encourages one evolving schema. You add new fields freely, and because clients only receive fields they ask for, adding things does not break anyone. Old fields can be marked deprecated and removed once nobody uses them.
Typing and documentation
A GraphQL schema is strongly typed, and the server can describe itself to tools through introspection. GraphiQL uses this to offer autocomplete and built-in documentation.
REST has no built-in schema, though you can describe a REST API with Swagger, now known as the OpenAPI Specification. Our article on the OpenAPI Specification explains how that works. It is an extra step rather than part of the style itself.
Caching
This is where REST has a clear edge. Because each resource has its own URL and GET requests are cacheable, browsers, reverse proxies and CDNs can cache REST responses using standard headers such as Cache-Control and ETag.
GraphQL queries are usually sent as POST requests to one URL, so HTTP caching does not help much. Caching moves into the client (Relay keeps a normalised store of objects) and into your server code. That works, but it is your job to build it.
Error handling
REST uses HTTP status codes: 404 for not found, 401 for unauthorised, 500 for server errors. Monitoring tools understand these.
A GraphQL server typically returns 200 with an errors array in the body, and a query can partly succeed. Your logging and monitoring need to look inside responses to spot problems.
Performance and security on the server
A flexible query language lets clients ask for a lot. A deeply nested query can trigger hundreds of database calls if you are not careful. You will need to batch and cache data loading (Facebook has released a small library called DataLoader for this in JavaScript), limit query depth and complexity, and watch for slow queries. REST endpoints are easier to reason about because each one does a known amount of work.
File uploads and other edges
Uploading files, streaming and real-time updates are not covered well by the current GraphQL specification. Real-time support is being discussed, but today you would handle these needs outside GraphQL or with your own conventions. REST handles uploads with ordinary multipart requests.
When REST is the better choice
- Public APIs used by third parties. Most developers know REST, and every language has HTTP tools. A GraphQL API asks your partners to learn something new.
- Simple, resource-shaped data. If clients mostly fetch one kind of object at a time, GraphQL adds complexity for little gain.
- Heavy caching needs. Content that is read far more often than it changes benefits from CDN and browser caching.
- Teams outside the JavaScript world. The best GraphQL tooling is in Node.js. Implementations in other languages are improving, but some are early.
- Integrations with existing systems. Most third party services, from payment gateways to CRMs, expose REST APIs. If your job is to connect systems, REST is what you will be working with. See our guide to API integration for more on that.
When GraphQL is worth considering
- Several clients with different needs. A web app, an iOS app and an Android app often want different slices of the same data. GraphQL lets each ask for what it needs without new endpoints.
- Deeply related data. Social features, dashboards and product catalogues with many connections benefit from fetching a graph in one request.
- Mobile apps on slow networks. Fewer round trips and smaller payloads matter here.
- Fast-moving front-end teams. Front-end developers can change what a screen shows without waiting for a new endpoint.
- A React front end. If you already use React, Relay gives you a structured way to fetch data per component.
Can you use both?
Yes, and many teams will. A common pattern is to keep existing REST services in place and put a GraphQL layer in front of them, so mobile and web apps talk to GraphQL while the GraphQL server calls REST services or databases behind the scenes. This lets you try GraphQL on one app without rewriting your back end. It also fits well with a microservices setup, where a single GraphQL endpoint pulls data from several services.
The reverse also works: keep REST for your public API and use GraphQL internally for your own apps.
Questions to ask before you choose
- Who will use the API: your own apps, partners, or the public?
- How many different clients will there be, and how different are their needs?
- How much of your traffic could be served from cache?
- What language is your back end written in, and how mature is the GraphQL library for it?
- Does your team have time to learn new tools and build query limits and monitoring?
- Will you need file uploads or real-time features soon?
If most answers point to simple data, outside users and heavy caching, choose REST. If they point to several in-house clients, complex data and a JavaScript-friendly team, GraphQL deserves a prototype.
FAQ
Is GraphQL replacing REST?
No. GraphQL is a new option that solves particular problems well. REST remains the standard for most APIs and will be for a long time.
Is GraphQL only for React and Facebook-style apps?
No. Any client that can send an HTTP request can use a GraphQL API. Relay is tied to React, but you can query a GraphQL server from plain JavaScript, iOS, Android or a server-side script.
Is GraphQL ready for production?
Facebook has run it in production for years. The specification is still a working draft and the wider ecosystem is young, so expect to write more of your own tooling than you would with REST.
Pick the style that fits the job
Neither style is better in every case. The right choice depends on who uses your API, how your data is shaped and what your team can support. If you are planning a new API or a mobile app back end and want a second opinion, see our custom development services.