Edgio provides full support for caching GraphQL APIs. Putting Edgio in front of your GraphQL API can significantly improve its performance while reducing the amount of traffic that reaches your origin by serving cached queries from the network edge.
Example
The sections below walk you through configuring your Edgio project and creating the necessary routing rules to cache GraphQL responses.
Project Configuration
To deploy Edgio in front of your GraphQL API, install the Edgio CLI and create a new Edgio configuration:
Bash
1$ npm i -g @layer0/cli # yarn global add @layer0/cli2$ 0 init
For more information on adding Edgio to an existing app, see Getting Started.
Configure the Origin
To configure the origin domain from which your GraphQL API is served, add a backend to
layer0.config.js
. For example:JavaScript./layer0.config.js
1// layer0.config.js2module.exports = {3 backends: {4 graphql: {5 domainOrIp: 'graphql-origin.my-site.com', // the hostname for your origin graphql server(s)6 hostHeader: 'graphql.my-site.com', // the hostname that clients use to connect to your graphql api7 },8 },9}
Add Caching Rules
There are two ways to cache GraphQL responses using Edgio: by adding caching rules to your Edgio router or by using the
cache-control
header.Using the Edgio Router
Imagine you have a query named
GetProduct
:JavaScript
1export const GET_PRODUCT_QUERY = gql`2 query GetProduct {3 product(id: $productId) {4 name5 description6 price7 }8 }9`
You can add a caching rule for this query by using the
graphqlOperation
method, which is designed to comply with the operationName
convention of the Apollo client ecosystem.JavaScript./routes.js
1import { Router } from '@layer0/core'23export default new Router().graphqlOperation('GetProduct', ({ cache, proxy }) => {4 cache({5 edge: {6 maxAgeSeconds: 60 * 60, // cache responses for one hour7 staleWhileRevalidateSeconds: 60 * 60 * 24, // serve stale responses for up to 24 hours8 },9 })10 proxy('graphql') // forward requests to the GraphQL API origin we defined in layer0.config.js11})
Match Operations by Regular Expression
The
graphqlOperation
method also allows you to match operations using a regular expression:JavaScript
1export default new Router().graphqlOperation(/product/i, ({ cache, proxy }) => {2 /* ... */3})
Alter the Default GraphQL API Path
Most GraphQL APIs are hosted on the
/graphql
path. The graphqlOperation
method will only match requests sent to /graphql
by default. To use a different path, specify the path
option:JavaScript
1export default new Router().graphqlOperation(2 {3 path: '/gql-api' /* override the default /graphql path */,4 name: 'GetProduct' /* name can also be a regular expression */,5 },6 ({ cache, proxy }) => {7 /* ... */8 },9)
Use the Cache-Control Header
Edgio supports caching GraphQL responses at the network edge using the standard
cache-control
HTTP response header. For example, to cache the results of a query for one hour, add the following header to your response:1cache-control: max-age=3600
You can also serve stale responses while fetching a fresh response from the origin by using
stale-while-revalidate
. For example, to allow stale responses to be served for up to 24 hours, use:1cache-control: max-age=3600, stale-while-revalidate=86400
Cache Key
Regardless of the method you choose to define caching rules, Edgio incorporates the request body into the cache key for all
POST
requests. This means that if two requests have different request bodies,
their responses will be cached separately.Invalidate Stale Queries
Edgio gives you the ability to purge individual queries from the edge cache by assigning surrogate keys to each cached response.
Assign Surrogate Keys
To invalidate a cached query, you must first assign a surrogate key to the response before it is cached. You can do this using the router:
Use deriveSurrogateKeysFromJson
JavaScript./routes.js
1import { Router, deriveSurrogateKeysFromJson } from '@layer0/core'23export default new Router().graphqlOperation('GetProduct', ({ cache, proxy }) => {4 cache({5 edge: {6 maxAgeSeconds: 60 * 60, // cache responses for one hour7 staleWhileRevalidateSeconds: 60 * 60 * 24, // serve stale responses for up to 24 hours8 },9 })10 proxy('graphql', {11 // Assigns a surrogate key to each response12 transformResponse: deriveSurrogateKeysFromJson(json => [`product.${json.id}`]),13 })14})
Use the x-0-surrogate-key Response Header
You can also assign surrogate keys by adding an
x-0-surrogate-key
header to the response from the origin. Separate multiple keys with spaces:1x-0-surrogate-key: key1 key2 key3
Handle Conflicts
If the origin returns an
x-0-surrogate-key
response header and deriveSurrogateKeysFromJson
is also used for a given request, you can specify whether the surrogate keys should be merged, or the ones
from the router should override those in the origin response:To merge surrogate keys:
JavaScript
1deriveSurrogateKeysFromJson(json => [`product.${json.id}`], { onConflict: 'merge' })
To ignore the surrogate keys from the origin:
JavaScript
1deriveSurrogateKeysFromJson(json => [`product.${json.id}`], { onConflict: 'override' })
Purge by Surrogate Key
To purge all responses with a given surrogate key, use the Edgio CLI’s cache-clear command.
Bash
1layer0 cache-clear --team=my-team --site=my-site --environment=production --surrogate-key="product.1"
For more information, see clearing the cache from the CLI.
You can also purge responses by surrogate key via the REST API by specifying the
surrogateKeys
option.