REST and GraphQL APIs: Architecture, Caching, and Gateways

API7.ai

August 8, 2025

API 101

REST and GraphQL can coexist in the same API platform, but they place responsibilities in different parts of the system. REST organizes interfaces around resources and HTTP operations. GraphQL exposes a typed schema and executes client-selected fields. Those differences affect request processing, caching, authorization, observability, and gateway policy design.

Key Takeaways

  • The request models differ: REST maps methods and resource URLs to handlers, while GraphQL validates an operation against a schema and resolves its selected fields.
  • A schema does not replace implementation controls: GraphQL provides a built-in type system. REST commonly uses OpenAPI, but either style still needs runtime validation, authorization, compatibility tests, and change management.
  • Flexible selection changes server work: A compact GraphQL request can trigger many resolver and downstream calls. Operators need query limits, batching, timeouts, and field-level telemetry.
  • Caching happens at different layers: REST responses align naturally with HTTP cache keys. GraphQL often combines client-side normalized caches, resolver or data-layer caches, persisted operations, and gateway controls.
  • Gateways need protocol-aware policies: Authentication and transport limits apply to both styles, but GraphQL also benefits from operation parsing, depth or complexity controls, and visibility by operation rather than URL alone.
  • Hybrid stacks are common: A GraphQL aggregation layer can call REST services, while REST remains appropriate for resource APIs, webhooks, files, and independently operated services.

How REST and GraphQL APIs Process Requests

A RESTful API typically exposes multiple resource URLs. The HTTP method communicates the requested action, and the path identifies the target resource:

GET /users/42 GET /users/42/orders?limit=10

The server routes each request to a handler. That handler authenticates the caller, validates path and query parameters, reads data, and returns a representation. Status codes and headers are part of the interface: for example, a successful read can return 200 OK, while an absent resource can return 404 Not Found.

A GraphQL API usually accepts an operation document at a GraphQL endpoint. The operation names fields and relationships to return:

query UserWithOrders($id: ID!) { user(id: $id) { id name orders(limit: 10) { id status } } }

The GraphQL service parses the document, validates it against the schema, coerces variables, and executes the selected fields. Field resolvers may read a database, call another service, or compute a value. The GraphQL specification defines the language, type system, validation, and execution behavior, but it does not prescribe a database or service architecture.

flowchart LR
    C[Client]

    subgraph REST["REST request path"]
        RR[Method and Resource URL]
        RH[Route Handler]
        RS[Resource Service]
        RR --> RH --> RS
    end

    subgraph GQL["GraphQL request path"]
        GD[Operation Document]
        GV[Parse and Validate]
        GE[Execute Selection Set]
        GR[Field Resolvers]
        GD --> GV --> GE --> GR
    end

    C --> RR
    C --> GD
    RS --> D[(Data and Services)]
    GR --> D

This distinction changes what operators can infer from an incoming request. A REST route such as GET /orders/{id} provides a useful policy and monitoring key. A GraphQL URL alone does not identify the work: two calls to /graphql can select entirely different fields and produce very different downstream load. GraphQL telemetry therefore needs the operation name, operation type, selected fields, execution time, and errors, with sensitive arguments excluded.

Schemas and Contract Enforcement

GraphQL has a schema at the center of its execution model. Object types, fields, arguments, input objects, enums, interfaces, and unions define which operations are valid. The service validates an operation before execution, and the schema supports introspection and tooling. This creates a strong contract for field names and value shapes.

REST does not require one schema language, but teams commonly describe HTTP interfaces with OpenAPI. An OpenAPI document can define paths, operations, parameters, security schemes, request bodies, response bodies, and reusable schemas. It can drive documentation, client generation, testing, and gateway validation.

The important operational difference is where enforcement occurs:

Contract concernREST with OpenAPIGraphQL
Available operationsPaths and HTTP methods in the API descriptionRoot query, mutation, and subscription fields
Input validationGateway, framework, or application validates parameters and bodiesGraphQL engine validates the document and coerces declared input types
Response shapeImplementation and conformance testing keep responses aligned with the descriptionSelection set and schema determine the response fields and declared types
DiscoverabilityPublished API documentation or developer portalSchema introspection and generated documentation, subject to access policy
EvolutionAdditive changes, explicit versions, and compatibility policiesAdditive fields and schema deprecation, followed by usage-based removal

Neither contract eliminates runtime checks. A valid request can still be unauthorized, too expensive, or semantically invalid. For example, a GraphQL input type can require an orderId, but the application must still verify that the caller can view that order. Similarly, an OpenAPI schema can validate the shape of a REST request without deciding whether the requested state transition is permitted.

Treat both descriptions as governed artifacts. Review breaking changes in CI, publish deprecations, identify consumers, and measure actual usage before removal. In a GraphQL service, field-level usage is especially valuable because a single endpoint does not reveal which parts of the schema clients depend on.

Data Fetching and Resolver Behavior

REST response shapes are normally chosen by the API producer. This makes server work relatively predictable for a given route, but a client may need several requests to assemble a screen. Producers can add sparse-field parameters, includes, or purpose-built endpoints when a general resource representation is inefficient.

GraphQL moves selection to the client. One operation can retrieve a user, recent orders, and shipment status without separate client round trips. That improves client control, but it does not guarantee efficient execution. Each selected field can invoke a resolver, and naïve resolver code can repeat downstream reads.

Consider an order list where each order resolves its customer independently:

1 query to load 50 orders 50 resolver calls to load 50 customers

This server-side N+1 pattern is different from a client making several REST calls. GraphQL implementations commonly batch and deduplicate resolver reads within a request, join data in the storage layer, or use an aggregation service designed for the query. The correct technique depends on ownership, consistency requirements, and the downstream protocol.

Operators should measure rather than assume:

  • resolver duration and error count by field;
  • downstream calls per operation;
  • database queries and rows examined;
  • response size and serialization time;
  • time spent waiting for parallel versus serial work;
  • cancellation behavior when the client disconnects or a deadline expires.

Mutations need similar care. The GraphQL specification executes top-level mutation fields serially, but a resolver can still call several systems. Define idempotency behavior, timeouts, compensation, and error mapping for those downstream actions. For REST, apply the same discipline to operations that retry or coordinate multiple services.

Caching and CDN Behavior

REST reads commonly use GET with a resource URL, which gives browsers, CDNs, and shared proxies a natural cache key. Response headers such as Cache-Control, validators such as ETag, and authorization rules determine whether and how a response can be reused. RFC 9111 defines HTTP caching behavior; a route is not safely cacheable merely because it uses GET.

GraphQL is frequently sent as POST to one endpoint, so URL-based shared caching does not distinguish operations automatically. A GraphQL stack may combine several layers:

  • Normalized client cache: Stores entities by identity and updates views when a query or mutation changes those entities.
  • Resolver or data-source cache: Reuses eligible downstream reads while honoring tenant, authorization, and freshness boundaries.
  • Full-operation cache: Keys a response by the canonical operation, variables, identity context, and other inputs that affect the result.
  • Persisted operations: Maps a trusted identifier to a known operation, reducing request size and making operation-aware policy and caching easier.
  • CDN or gateway caching: Can cache carefully selected public or non-user-specific operations when transport, cache keys, and invalidation rules are explicit.

Cache keys must include every factor that changes a response. For authenticated data, that may include tenant, subject, role, locale, feature flags, and schema version. Omitting an authorization dimension can expose one user's data to another. Adding every header without thought, however, can make the cache ineffective.

For both REST and GraphQL, document the freshness target and invalidation event before enabling caching. Do not cache mutations or sensitive responses by default. Verify provider and data-license terms when caching third-party results.

Security and Resource Controls

Authentication, authorization, TLS, input limits, rate limits, audit logs, and safe error handling apply to both API styles. GraphQL adds a broad request surface behind a small number of URLs, so a gateway or GraphQL service needs visibility beyond request count.

Useful GraphQL controls include:

  • allow only supported operation types on each route;
  • limit document bytes, tokens, aliases, depth, and total field selections;
  • assign cost weights to fields that trigger expensive work;
  • cap page sizes and require bounded pagination;
  • restrict batching when it could bypass per-operation limits;
  • enforce an execution deadline and propagate cancellation downstream;
  • authorize at the object and field level, not only at the endpoint;
  • redact variables and field values from logs;
  • govern introspection according to the audience and threat model;
  • prefer trusted persisted operations for tightly controlled clients where practical.

Depth alone is not a complete cost model. A shallow field can run an expensive search, while a deeper query over cached small objects can be inexpensive. Combine structural limits with field cost, downstream budgets, rate limits, and observed execution data.

REST also needs workload-aware controls. A single export endpoint or unbounded search can be more expensive than many ordinary resource reads. Rate-limit by consumer and operation, validate pagination, and set response-size and execution limits based on the route's behavior.

Return errors without exposing stack traces, credentials, internal hostnames, or database details. GraphQL may return partial data alongside field errors, so monitoring should distinguish transport failures, request-validation failures, and execution errors even when the HTTP exchange succeeds.

Operating REST and GraphQL Through an API Gateway

An API gateway provides a shared control point before REST and GraphQL services. Protocol-neutral policies can terminate TLS, authenticate consumers, enforce coarse quotas, attach request IDs, and collect access logs. Protocol-aware policies then use REST route metadata or GraphQL operation metadata.

Operational concernREST gateway policyGraphQL-aware gateway policy
Policy identityMethod, normalized route, consumerOperation type, operation name or persisted ID, consumer
ValidationPath, parameter, header, and body schemaParse document, validate operation, constrain variables and structure
Rate limitingRequests or weighted units per routeRequests plus estimated or measured operation cost
CachingMethod, URL, query, headers, identity contextOperation or persisted ID, variables, identity context
ObservabilityStatus, route, upstream, latencyOperation, fields or resolver groups, errors, upstream calls, latency
RoutingRoute to service or versionRoute by operation or forward to a GraphQL router and subgraphs

Do not log raw GraphQL documents and variables by default. They can contain personal data, tokens, search terms, or business identifiers. Prefer a normalized operation signature, a trusted persisted-operation ID, and allowlisted metadata.

Gateway timeouts must align with downstream deadlines. If the gateway stops waiting but the GraphQL service and its resolvers continue working, abandoned requests can still consume capacity. Propagate deadlines and cancellation where the framework and downstream protocols support them.

For subscriptions, long-lived connections require separate connection, authentication-refresh, concurrency, and idle-timeout policies. They should not automatically inherit settings designed for short REST or GraphQL query requests.

Hybrid Architecture Pattern

A hybrid design often places GraphQL at the experience or aggregation layer while keeping REST services behind it. This lets product clients request a coordinated view without forcing every backend team to adopt GraphQL.

flowchart LR
    W[Web Application]
    M[Mobile Application]
    X[External REST Consumer]
    G[API Gateway]
    Q[GraphQL Aggregation Layer]
    U[User REST Service]
    O[Order REST Service]
    I[Inventory Service]

    W --> G
    M --> G
    X --> G
    G --> Q
    G --> U
    Q --> U
    Q --> O
    Q --> I

Keep ownership boundaries explicit:

  1. Backend services own their domain rules and stable service contracts.
  2. The GraphQL layer owns the client-facing schema, composition, resolver budgets, and field deprecation.
  3. The gateway owns application-facing authentication, routing, global traffic policy, and transport telemetry.
  4. Each layer propagates identity, trace context, and deadlines without trusting user-supplied internal headers.

Avoid turning the aggregation layer into an unbounded business-logic monolith. If a resolver implements a cross-domain transaction, decide which service owns that workflow and how failures are recovered. If clients need bulk transfer, file download, webhook delivery, or a simple resource endpoint, REST may remain the clearer interface even when the same product also exposes GraphQL.

Schema composition introduces deployment coordination. Validate subgraph or service changes before publication, test representative operations, and keep a rollback path for the composed schema. The GraphQL layer should degrade predictably when an optional backend is unavailable rather than converting every partial dependency failure into a platform-wide outage.

This guide focuses on implementation and operation. For a decision-oriented review of use cases, team trade-offs, performance considerations, and adoption criteria, read the primary GraphQL vs. REST API comparison.

Then continue with:

For a production design that combines REST, GraphQL, and shared gateway policies, contact API7 experts.