Sooner or later, every backend developer runs into the same fork in the road: should this project expose a REST API or a GraphQL one? The REST vs GraphQL debate has been running for years, and the honest answer is that neither one wins outright. They solve overlapping problems with very different trade-offs, and the right choice depends far more on your team and your data than on which one is trendier this quarter.
I have shipped both. Here is how I actually think about the decision when I am staring at a blank repository.
What REST gets right
REST models your API as a set of resources, each living at its own URL: /users, /users/42, /users/42/orders. You use HTTP verbs (GET, POST, PUT, DELETE) to act on them. It is simple, it is predictable, and it rides on top of everything the web already gives you for free.
That last point is the big one. Because REST leans on plain HTTP, you get caching, status codes, and CDN support without inventing anything. A GET /articles response can be cached at the edge and served to thousands of readers without ever touching your server. That is hard to give up.
What GraphQL gets right
GraphQL flips the model. Instead of many endpoints, you expose a single one and let the client describe exactly what it wants:
query {
user(id: 42) {
name
orders(last: 3) {
total
placedAt
}
}
}
The server returns precisely those fields, nothing more. This kills two classic REST annoyances: over-fetching (downloading a fat user object when you only needed the name) and under-fetching (making three round trips to assemble one screen). For a mobile app juggling a dozen data sources on one page, that is genuinely liberating.
Where the trade-offs bite
GraphQL’s flexibility has a cost. Caching is harder because everything is a POST to one URL, so you cannot lean on HTTP caches the way REST does — you end up adding a client cache like Apollo or a persisted-query layer. A carelessly written query can also ask for deeply nested data and hammer your database, so you need depth limiting and query-cost analysis in production.
REST’s weakness is the mirror image: it is rigid. When the front-end needs a new combination of data, someone often has to add or reshape an endpoint. Teams paper over this with query parameters and “include” flags until the API feels like GraphQL with worse ergonomics.
How to actually choose
Reach for REST when your data is fairly resource-shaped, when public cacheability matters, or when you want the lowest possible operational overhead. It is still the correct default for most CRUD services and public APIs.
Reach for GraphQL when many different clients need many different shapes of the same data, when you are aggregating several backends, or when front-end teams iterate fast and you want to stop shipping a new endpoint every sprint.
And remember it is not exclusive. Plenty of healthy systems expose REST for simple public access and GraphQL for a rich internal app, or wrap existing REST services behind a GraphQL gateway. The REST vs GraphQL question is really “which one fits this surface,” and you are allowed to answer it more than once.
The bottom line
Do not pick based on hype. Pick based on how your clients consume data, how much you value HTTP-level caching, and how much operational complexity your team can carry. Get those three answers right and the choice usually makes itself.

