Architecture Tradeoff Explorer

Every comparison answers the same five questions — use when, avoid when, complexity, operational cost, failure modes — so the decision is about your constraints, not the fashion of the year.

REST exposes resources with stable shapes that proxies and CDNs understand; GraphQL exposes a typed graph that clients query for exactly the fields they need. The decision is about how many client shapes exist and who pays for query flexibility.

REST
API Architecture: REST, GraphQL, RPC, gRPC, WebSockets, Webhooks
GraphQL
API Architecture: REST, GraphQL, RPC, gRPC, WebSockets, Webhooks
Use whenPublic APIs, cacheable reads, long-lived versions, clients you do not control. Anything you want to debug with curl.Several first-party client teams need different shapes of one connected graph, and endpoint-per-screen sprawl or five round trips per page is a measured problem.
Avoid whenScreens need many different projections of deeply related data and every new screen spawns a new endpoint or ?include= parameter.The API is public and you cannot bound query cost, or the data is a handful of flat resources where a BFF would do.
ComplexityLow: HTTP verbs, status codes, an OpenAPI document; caching and auth at the gateway.Medium-high: schema, resolvers with batching (DataLoader), depth and cost limits, persisted queries, federation if the graph spans services.
Operational costStandard HTTP tooling; GET responses cached by URL and ETag at every layer.Every query is a POST to one endpoint, so HTTP caching is lost; per-query cost varies, so rate limiting must be by complexity, not by request.
Failure modesOver/under-fetching that grows into ad-hoc query parameters; N+1 client round trips when resources mirror tables; breaking changes shipped as the same version.N+1 resolvers (38 orders → 38 customer queries, visible as 38 sequential spans); unbounded nested queries from the internet; one slow field slowing every query that includes it.
Data flowClient → GET /orders/42 → one resource; related data via further requests or embedded fieldsClient → POST /graphql with a query → resolvers walk the graph → one response shaped by the query
VersioningURL or header versions; a version is a contract you keep for yearsAdditive schema evolution; fields are deprecated, not versioned
Type safetyFrom the OpenAPI document, if generated and enforcedFrom the schema, built in; introspection drives tooling
Team shapeBackend owns endpoints per client needBackend owns the schema; clients own their queries