Stop asking “should we use GraphQL?” Start asking “what problem am I actually solving?” Because nine times out of ten, the answer to the first question is “it depends,” and that helps nobody.
I’ve been on both sides of this. At the fintech startup we had a data-heavy product with financial news, watchlists, and user preferences all tangled together. Multiple clients, each wanting different slices of the same data. That’s where GraphQL earns its keep. At Dropbyke, the API was mostly bikes, locations, and rides. CRUD. REST was the obvious call and anything fancier would have been engineering theater.
The actual difference
REST is resource-oriented. Endpoints map to things. HTTP verbs describe what you’re doing. Simple.
GET /users/123
GET /users/123/posts
GraphQL is query-oriented. One endpoint, clients ask for exactly what they need. Less payload, fewer round trips. But now you own the complexity of parsing and costing arbitrary queries.
query {
user(id: "123") {
name
posts(limit: 10) {
title
}
}
}
That’s it. That’s the fork in the road.
Where GraphQL actually helps
Over-fetching and under-fetching. The classic problem. Your mobile app needs three fields, your web dashboard needs thirty, and your REST endpoint returns everything because that was easier than maintaining two versions. GraphQL fixes this. Each client asks for what it wants. Done.
The schema-as-contract thing is real too. At the fintech startup we had backend and frontend teams moving at different speeds. Having a typed schema meant fewer “wait, when did this field change?” conversations. Fewer surprises at 11pm.
And versioning basically goes away. New fields don’t break old clients because old clients never asked for them. You just… add stuff. Compare that to /api/v1/ vs /api/v2/ hell.
Where REST still wins
Most APIs are boring. I mean that as a compliment. You’re creating, reading, updating, and deleting resources. REST maps perfectly to that. Everyone on your team already knows how it works. No learning curve, no new tooling.
Caching is the big one though. GET requests, ETags, CDN behavior – all of it works out of the box with REST. You can cache GraphQL, sure. But you’ll build infrastructure to do it. At Dropbyke we leaned hard on HTTP caching for location data. Would have been painful with GraphQL for no real benefit.
Monitoring and auth are also simpler. You know which endpoint got hit. You can rate-limit per endpoint. Your APM tools just work. With GraphQL, one POST to /graphql could be fetching a user’s name or joining six tables. Good luck setting up alerts for that without extra instrumentation.
So which one?
GraphQL makes sense when:
- Multiple client types with genuinely different data needs
- Product surface changes constantly and frontend is blocked waiting on backend
- Data model is deeply connected and clients traverse relationships
REST makes sense when:
- API is mostly CRUD
- HTTP caching matters (it usually does)
- Team wants to ship fast without new tooling overhead
- External consumers expect standard REST
Use both. Seriously.
This is the part people overthink. REST for your public API where caching and stability matter. GraphQL for your internal product API where flexibility matters. Two tools, two jobs. Nobody gives you a prize for picking just one.
The stuff nobody warns you about
GraphQL without guardrails will ruin your week. Query depth limits, complexity scoring, resolver instrumentation, N+1 batching – you need all of it before you go to production. I’ve seen a single GraphQL query bring a service to its knees because nobody thought to limit nesting depth. Fun times.
REST without conventions will also ruin your week, just slower. Inconsistent naming, no versioning strategy, undocumented side effects. Death by a thousand papercuts.
Bottom line
Don’t pick the exciting one. Pick the boring one. The one that matches your actual constraints, your team’s actual skills, and your product’s actual needs. If that’s REST, great. If that’s GraphQL, also great. If it’s both, welcome to the club.