We've shipped production systems with both REST and GraphQL. The choice matters less than the implementation quality, but the right choice for your context does matter. Here's the framework.
REST is the right default
REST is simple, well-understood, cacheable by default, and has excellent tooling across every language and platform. HTTP caching (CDN, browser, proxy) works out of the box. OpenAPI/Swagger gives you documentation and SDK generation. Every engineer on your team knows how to work with it.
For most APIs — internal service-to-service, public third-party APIs, mobile backends with stable data requirements — REST is the right choice. Choose REST unless you have a specific problem that GraphQL solves better.
When GraphQL solves real problems
Complex, variable data requirements: When different clients (web, iOS, Android, third-party) need different shapes of the same data, and maintaining multiple REST endpoints or query parameters is becoming unwieldy.
Rapid frontend iteration: When the frontend team is moving faster than the backend team can add endpoints. GraphQL lets frontend engineers fetch exactly the data they need without waiting for a new endpoint.
Aggregation layer: A GraphQL API as a BFF (Backend for Frontend) that aggregates multiple REST microservices into a single query interface. This is one of GraphQL's strongest use cases.
GraphQL trade-offs that hurt
Caching: REST gets HTTP caching for free. GraphQL sends everything as POST to a single endpoint — no CDN caching without additional tooling (persisted queries, Apollo CDN). N+1 queries from nested resolvers require DataLoader. These are solvable problems, but they require explicit effort.
Security: GraphQL's flexibility is also its attack surface. Depth limiting, complexity limits, and field-level authorisation require explicit implementation. A naive GraphQL server is trivially DoS'd with deeply nested queries.
The hybrid answer
Many production systems use REST for simple CRUD and data-retrieval endpoints, and GraphQL for complex, multi-entity queries. There's no rule that says you must pick one. Use the right tool for the specific use case.