GraphQL and REST: compare needs, costs and access controls

At a glance

GraphQL lets clients select fields from a typed schema. It can complement REST; neither approach is automatically faster or safer for every workload.

Empty secure server and network corridor Illustration · fictional scene
In this article

Understand the request and its cost

This example uses a fictional schema: customer, orders and total must exist in the actual API. One request can aggregate data while triggering several server-side reads. REST can also provide tailored responses. A single HTTP endpoint is common in GraphQL, rather than mandatory for every architecture.

query RecentOrders($id: ID!) {
  customer(id: $id) {
    name
    orders(first: 5) {
      nodes { id total }
    }
  }
}

Compare a representative task

  • Measure bytes, latency, errors and server work for the same screen, permissions and realistic data volumes.
  • Check pagination, batched reads to limit N+1 behavior, caching strategy and isolation between accounts.
  • Assess schema evolution, compatibility with older clients, observability and operating effort. Retaining REST may be the simpler choice.

Enforce rights and workload limits

Authenticate requests, then authorize objects and fields in business logic. Bound list sizes, depth, aliases, batched operations and estimated cost; request frequency alone does not describe workload. Hiding introspection does not replace these controls. Test denied access and partial responses too.

Primary references

Govern the GraphQL schema and query cost

GraphQL lets clients select fields, but that flexibility calls for object and field authorization. A size or depth cap alone does not replace measuring the work a query causes.

  • Test sensitive fields and objects owned by another account.
  • Limit and observe cost, depth and request volume for the service.
  • Version schema changes and exercise older clients.

Primary reference: OWASP — GraphQL Cheat Sheet. Related method: read the practical guide.

ETag, HTTP caching and concurrent updates

REST and GraphQL: separate representation and authorisation

An HTTP ETag applies to a selected representation. It is neither permission for every returned object nor a universal consistency contract for GraphQL entities.

  • Define which response variants have their own validators.
  • Test object and field access independently from HTTP conditions.
  • Do not automatically apply the PUT scenario to a GraphQL mutation; specify its concurrency contract.

Explore ETag comparisons and the simulator →

References reviewed · RFC 9110 · §13 · RFC 9111 · RFC 6585 · §3