Node.js › GraphQL

How would you implement caching for a GraphQL API, given that unlike REST, a single endpoint serves widely varying query shapes that don't map cleanly to standard HTTP caching?

Advanced

Answer

Because GraphQL typically uses a single POST endpoint (making standard HTTP/CDN caching based on URL largely ineffective, since every distinct query looks identical at the HTTP level) and different clients request different field combinations, caching strategies instead operate at other levels: persisted queries (registering common queries server-side ahead of time and referencing them by a short hash, which also enables safe GET-based caching), response caching keyed by the specific query and variables combination, and field-level or entity-level caching (like Apollo Server's cache hints, specifying how long a specific type or field's data should be cached) integrated with a backing store like Redis.
const resolvers = {
  Query: {
    product: (_, { id }, { cache }) => {
      // Apollo cache hints: this field's result can be cached for 60 seconds
      return cache.wrap(`product:${id}`, () => db.products.findById(id), { ttl: 60 });
    },
  },
};
Real-world example A high-traffic GraphQL API implements Automatic Persisted Queries, letting the CDN cache and serve the vast majority of repeated identical queries via GET requests keyed by a short query hash, dramatically reducing load on the origin GraphQL server for its most common queries.

Common follow-ups: How do Automatic Persisted Queries specifically enable GET-based caching that a typical GraphQL POST request can't achieve?;What's the tradeoff of field-level cache hints versus caching an entire query's response as a single unit?