Where These Two Approaches Come From
REST has been around since Roy Fielding described it in his doctoral dissertation in 2000. It's not a protocol — it's an architectural style built on HTTP verbs (GET, POST, PUT, DELETE) and resources addressed by URIs. Because it maps cleanly onto the web's own conventions, REST spread fast and is now the default shape of most public APIs you'll encounter.
GraphQL is younger and more opinionated. Facebook developed it internally to solve real problems with mobile data fetching, and open-sourced it in 2015. Where REST hands you a fixed set of resource endpoints, GraphQL gives clients a typed schema and a query language: you describe the shape of data you want, and the server returns exactly that — nothing more, nothing less.
Both styles solve the same core problem (getting data across a network) but with different philosophies about where decisions live. REST puts them on the server; GraphQL moves more of them to the client.
The Problems Each One Solves — and Creates
REST's biggest practical friction is over-fetching and under-fetching. Hit /users/42 and you might get thirty fields when your UI needs four. Hit /users/42/posts separately when you also need comment counts, and you've made two round trips for data that's logically one request. This is fine at small scale and becomes genuinely painful in mobile contexts where bandwidth and latency matter.
GraphQL was built specifically to solve that. A single query can traverse multiple types, pull related data, and return exactly the fields the client asked for — in one request. That's not a marketing claim; it's a structural property of how a query resolves against a schema.
query {
user(id: "42") {
name
posts(last: 5) {
title
commentCount
}
}
}That query returns the user's name and their five most recent post titles with comment counts. No extra fields. One round trip. In REST you'd wire this up with either a custom endpoint or multiple requests.
The tradeoff is complexity. A REST API can be understood by reading a list of routes. A GraphQL API requires a schema, a resolver layer, and tooling to work with both. Caching — trivially handled by HTTP in REST (URLs are cache keys) — becomes something you have to solve deliberately in GraphQL, usually through libraries like Apollo Client or by operating at the persisted-query level.
There's also the learning curve for teams. REST uses HTTP conventions most developers already know. GraphQL introduces its own type system, its own query language, mutations for writes, and subscriptions for real-time data. That's real investment before you ship anything.
How to Actually Choose
The choice isn't "GraphQL is modern, REST is legacy." It's about the mismatch between your data shape and your clients' needs.
REST is a better fit when your API is primarily resource-CRUD, your clients are relatively uniform, you want HTTP caching out of the box, or you're building something that external developers will consume. A public REST API with well-versioned endpoints and clear documentation is still the most accessible interface you can ship. Versioning in REST — /v1/, /v2/ — is a solved problem, even if it's a bit tedious.
GraphQL earns its keep when you have multiple clients (web, iOS, Android) with genuinely different data requirements, when you're aggregating data across several backing services into one coherent schema, or when over-fetching is a measurable performance problem. The single-endpoint model (POST /graphql) and the schema as a contract between frontend and backend teams are legitimately useful in those contexts.
One thing GraphQL doesn't solve is versioning in the traditional sense — you evolve the schema instead, deprecating fields rather than bumping a version number. That's often cleaner in practice, but it means clients can rely on fields that are quietly on their way out, so schema governance matters.
The Practical Takeaway
For a new internal API serving a product with several surfaces, GraphQL's flexibility pays off quickly. For a public API, a microservice with a narrow purpose, or a small team that wants to ship without new tooling overhead, REST is still the right default — and building an API that lasts comes down to the boring decisions (error formats, versioning, consistent naming) that neither style makes automatic. Neither GraphQL nor REST removes the need to think carefully about your API design; they just give you different shapes to think in.
