The REST vs GraphQL debate has been running since 2015, and it still generates more heat than light. Having built APIs in both for 40+ client projects, I can give you a clear, opinionated answer — not a "it depends" cop-out, but an actual framework for making the decision.
REST: Still the Default for Good Reason
REST's strengths are its universality and simplicity. Every HTTP client can speak REST. Caching is trivial (CDNs understand GET requests natively). Error handling is standardised. Tooling — Postman, Swagger, Insomnia — is mature. For a public API, a microservice backend, or a simple mobile app, REST is almost always the right default.
// REST endpoint — simple, predictable, cacheable
router.get('/products/:id', async (req, res) => {
const product = await Product.findById(req.params.id)
.populate('category')
.populate('variants');
if (!product) return res.status(404).json({ error: 'Not found' });
res.json({ data: product });
});
GraphQL: When It Shines
GraphQL eliminates over-fetching and under-fetching — the two chronic problems of REST. Instead of hitting three endpoints to build a dashboard screen, you make one query that returns exactly the fields you need. This matters most when: you have multiple client types (web, mobile, TV) with different data needs, your data graph is complex and deeply relational, or your frontend team and backend team have different release cadences.
# One query, exactly the data needed for the dashboard
query Dashboard(: ID!) {
user(id: ) {
name
avatar
stats {
totalOrders
totalSpend
}
recentOrders(limit: 5) {
id
status
total
items { name quantity }
}
}
}
The Decision Matrix
- <strong>Choose REST if:</strong> You're building a public API, you need HTTP caching, your team is new to GraphQL, or your API has simple, predictable data access patterns.
- <strong>Choose GraphQL if:</strong> You have multiple client types with different data needs, your data model is a graph (social, e-commerce, CMS), or you need a self-documenting API that frontend teams can explore independently.
- <strong>Consider both:</strong> Large platforms often use REST for public APIs and GraphQL for internal frontend-to-backend communication. This is what GitHub, Shopify, and Twitter do.
GraphQL's Real Costs
GraphQL is not free complexity. You gain developer experience and flexibility at the cost of: harder caching (you need persisted queries or a CDN that understands GraphQL), N+1 query problems (requires DataLoader or similar), more complex security (you can't rate-limit by endpoint, you need query depth/complexity limits), and a steeper learning curve for your backend team. These are solvable problems — but they're real costs to budget for.
Start with REST. It's boring, and boring is good. If you find yourself writing lots of custom endpoints for specific screen data requirements, that's your signal to evaluate GraphQL. Migrate incrementally, never all at once.
Got a project in mind?
I work directly with founders and CTOs to build reliable, scalable software. Let's have a conversation about your goals.
Get a Quote