Partial Query Caching Cookbook

Partial Query Caching is our new and innovative caching implementation, and it enables you to deploy a multitude of different caching strategies, most of which were not possible with Document Caching.

The following is a list of mini-guides that are designed to help you solve common use-cases with Partial Query Caching. Each section can be read on its own.

Incremental Caching Adoption

It can be a significant undertaking to properly and correctly set up caching for your complete GraphQL API all at once. Partial Query Caching enables you to set a default of not caching anything, and then selectively pick types or fields that can be cached.

import { Config } from 'stellate'

const config: Config = {
  config: {
    name: 'ecommerce-api',
    partialQueryCaching: { enabled: true },

    // Declare the query root type as non-cacheable. All other types and fields
    // will inherit this behavior by default.
    nonCacheable: ['Query'],

    rules: [
      // Add a cache rule that declares the `Product.name` and
      // `Product.description` fields as cacheable. Since this is more specific
      // than the default inherited from the `Query` type it will lead to these
      // two fields being split from any other fields in the query.
      { types: { Product: { name: true, description: true } }, maxAge: 3600 },
    ],
  },
}

export default config

The following query gives an example of how splitting happens given the prior config of this section:

{
  product(slug: "blue-sneakers") {
    id
    name
    description
    hasStock
    quantity
  }
}

Split out non-cacheable fields

A single GraphQL query can contain lots of different kinds of data, some being cacheable and some being non-cacheable. With document caching, even a single non-cacheable field would prevent the whole query from being cached. However, with Partial Query Caching those fields will simply be split into a separate entry.

import { Config } from 'stellate'

const config: Config = {
  config: {
    name: 'ecommerce-api',
    partialQueryCaching: { enabled: true },

    // Information about product availability is not cacheable.
    nonCacheable: ['Product.hasStock', 'Product.quantity'],

    rules: [
      // However, all other fields of the `Product` type are cacheable.
      { types: { Product: true }, maxAge: 3600 },
    ],
  },
}

export default config

The following query gives an example of how splitting happens given the prior config of this section:

{
  product(slug: "blue-sneakers") {
    id
    name
    description
    hasStock
    quantity
  }
}

Splitting lists

Splitting a query that returns a list of entities holds some special challenges, in particular if the order of entities is non-deterministic. As an example, imagine sending the following query and assume it's split into two parts:

{
  products {
    id
    name
    description
    hasStock
    quantity
  }
}

Cache Entry #1 is cacheable, so assume we have a list of products with ids 1, 2, and 3 in the cache. Cache Entry #2 is non-cacheable and thus will always be fetched from the origin. If the response of that request returns a different list of entities - for example, the products with ids 2, 3, and 4 - then the two partial responses cannot be merged into a complete response.

Our implementation of Partial Query Caching contains two safe-guards that ensure this does never happen.

  1. Key fields are required inside of lists - We can only validate that two or more lists contain the same entities if there exists a key field in the list items. Common examples for key fields are id, _id, or key fields. If there does not exist such a key field, Partial Query Caching will not split any selection sets inside of the list field.
  2. Entity mismatches lead to revalidation from the origin - If Partial Query Caching runs into mismatching entities, all parts of the affected lists are revalidated using a request to the origin. (Note that this could mean that some requests to your Stellate service will result in two requests to your origin, because we can only detect entity mismatches after we have collected all partial responses.)

Considerations

This page is a collection of guides to help you solve specific use-cases, and we're using simple examples so that they are easy to follow and understand. If you try to employ some of these strategies and encounter any issues or unknowns, we are dedicated to helping you be successful. You can contact customer success at support@stellate.co.

Discover more