The first two parts covered what GraphQL is and how a GraphQL conversation works. This part is the one to bring to a planning meeting: how REST and GraphQL compare, where each one shines and what to ask before your team commits to either.
The short answer is that neither is better. They make different trade-offs, and the right choice depends on the product, the team and who else will use the API.
The pros and cons
REST and GraphQL: the pros and cons
Pros
- Simple and familiar. Almost every developer and tool knows it, and you can try a GET in a browser's address bar.
- Easy to cache. Each address is its own answer, so browsers and networks can keep copies and save repeat trips.
- Clear when it fails. Status codes say how it went, and monitoring tools understand them out of the box.
- Predictable costs. Each address does a known amount of work, so limits and pricing per request are easy to reason about.
Cons
- Too much or too little. Fixed answers mean over-fetching, and screens that need related data make several trips.
- New screens wait for new endpoints. If no address returns what a design needs, the back-end team has to build one.
- Versions to manage. Breaking changes mean a
v2and a migration for everyone.
Pros
- Exactly what the screen needs. One request, only the fields asked for, which helps most on phones and slow connections.
- Front-end teams move faster. A new screen can often be built by writing a new query, with no back-end change.
- A typed schema. One menu of everything on offer, checked automatically, so typos and missing fields show up before release.
- Changes without versions. New fields can be added freely, and old ones marked as deprecated and retired once nobody asks for them.
Cons
- More to set up and learn. A schema, a server and new tooling, which is a lot for a small, simple API.
- Harder to cache. Every request goes to one address, usually as a POST, so the easy, address-based caching doesn't apply.
- Errors hide in 200s. Failures come back inside the answer, so monitoring and alerting need extra work.
- Expensive questions. One deeply nested query can ask for a huge amount of data, so servers need limits on how much a query may cost.
Side by side
Side by side
| Question | REST | GraphQL |
|---|---|---|
| How many addresses? | One for each thing: /countries, /countries/GB/languages | One for everything, usually /graphql |
| Who decides what comes back? | The API: each address has a fixed answer | The product: it lists the fields it wants |
| How do you ask? | GET, POST, PUT, PATCH, DELETE | Queries, mutations and subscriptions, almost always as a POST |
| How do you know it worked? | The status code: 200, 404, 500 | The status code and an errors list inside the answer |
| What's the documentation? | Written by the team, often with an OpenAPI file | The schema itself, which tools can read |
| How does it change? | New versions: v1, v2 | New fields are added, old ones deprecated |
| Caching | Built in, by address | Needs a client library or extra set-up |
| Best for | Simple, stable, public data and file downloads | Apps with many screens and lots of related data |
Which one fits?
Two examples from this site show the difference. The weather page asks one question, "what's the weather here?", and uses nearly everything in the answer. A REST API is perfect for that, and it lets the answer be cached. The country explorer lets you pick any mix of facts, some of which would live at different REST addresses. That's the kind of thing GraphQL was built for.
Which one fits?
- The data is simple and each screen needs one thing, like the weather page.
- Lots of people will ask the same question, so caching matters.
- Outside developers will use it and you want the lowest barrier to entry.
- It's a small team that doesn't need another layer to look after.
- Screens pull lots of related data together, like a product page with stock, reviews and delivery dates.
- Web, iPhone and Android apps each need a different slice of the same data.
- Front-end teams keep waiting on new endpoints to ship features.
- The data comes from several services that you'd like to offer through one front door.
It's often both
In practice, plenty of companies use both. A common pattern is a GraphQL layer in front of existing REST services, so the apps get one front door and the services don't need rewriting.
It's often both
The website and the mobile apps each send one GraphQL query per screen
Works out which services hold each field and asks them
Products, stock, reviews and delivery, each still a REST API of its own
If you're working with a third party, the choice is usually made for you: you use whatever they offer. Some, like GitHub and Shopify, offer both, and it's worth checking which one gets new features first.
Questions to ask before choosing
- Who will use it? Our own apps, partners or the public? Outside developers usually find REST easier to start with.
- How different are the screens? If web, iPhone and Android each need a different slice of the data, GraphQL earns its keep. If every screen wants the same thing, it may not.
- What's slowing us down today? If features keep waiting for new endpoints, GraphQL can help. If the problem is elsewhere, a new API style won't fix it.
- Does the team know it? GraphQL is a new skill, with new tooling. Is there time to learn it, and someone to look after the schema?
- How will we cache it? If lots of visitors ask the same thing, caching saves money and time. It's simpler with REST.
- How will we know it's broken? With GraphQL, monitoring has to read the errors inside each answer, not just the status code.
- How do we stop expensive queries? A GraphQL server needs limits on how deep or how big a query can be, especially if it's public.
See it working
The country explorer puts this series on one page. Pick a country and the facts you want, and the page writes the GraphQL query, sends it to the free Countries API and draws the card from the answer. "Behind the scenes" shows the live query and answer, plus the requests an imaginary REST version would have needed for the same card.
Once you know what to look for, you'll spot both styles everywhere: the REST call behind a delivery tracker, the GraphQL query behind a headless shop's product page. Each one is a product asking another service a question, and someone on the team deciding how much to ask for and what to show when the answer is incomplete.