Server-side Caching
The caching plugin adds the ability to specify a list of queries whose responses should be cached.
Setting up for local development
We can set up everything we need for local development through Docker. Add the following entries to your compose.yaml
file:
redis:
image: redis:latest
ports:
- 6379:6379
caching:
build:
context: https://github.com/hasura/engine-plugin-caching.git
ports:
- 8787:8787
extra_hosts:
- local.hasura.dev=host-gateway
volumes:
- ./globals/plugins/caching-config.js:/app/src/config.js
Here, we've added a Redis instance to our Docker Compose project, as well as an instance of the caching plugin. The
caching plugin takes a config file (which we've said here is saved in ./globals/plugins/caching-config.js
, though the
path is up to you). Here's an example config file:
export const Config = {
// Client header configuration
headers: {
// A secret that must be provided in incoming requests from the engine.
// Change this to whatever you'd like, though remember to update the
// references further on.
"hasura-m-auth": "zZkhKqFjqXR4g5MZCsJUZCnhCcoPyZ",
},
// How long a cached response should live (in seconds).
time_to_live: 600,
// A URL for redis. If you copied the docker-compose configuration for
// `redis` above, this doesn't need changing.
redis_url: "redis://redis:6379",
// OpenTelemetry configuration. The name of this environment variable will
// depend on your subgraph name - check your `.env` file to find the correct
// name. You can also specify any further headers that your telemetry
// collector may require.
otel_endpoint: process.env.GLOBALS_OTEL_EXPORTER_OTLP_ENDPOINT,
otel_headers: {},
// A list of queries that we want to cache. Note that these queries will be
// cached based on their parsed structures, so white space doesn't matter.
queries_to_cache: [
` query MyQuery {
customers {
firstName
lastName
}
}
`,
],
};
The queries_to_cache
list can be extended to contain all the queries you'd like to be cached. Note that the query
response is cached for each set of session variables and each role, as these may yield different outputs.
This example uses hard-coded values for the URLs and the request headers, though these can be dynamically and securely
injected using environment variables. Changing the value
key to valueFromEnv
allows us to specify the name of an
environment variable from which to get this information. Note that the variables are defined via the envMapping
config
in subgraph.yaml
, which states which environment variables should be inherited from the root .env
.
Adding the plugin to your project
Once we've configured the plugin, running ddn run docker-start
should work happily. Now, we just need to configure
Hasura to use the plugin. Add the following to one of your subgraph.yaml
files:
---
kind: LifecyclePluginHook
version: v1
definition:
pre: parse
name: cache_get_test
url:
valueFromEnv: HASURA_CACHING_PRE_PARSE_URL
config:
request:
headers:
additional:
hasura-m-auth:
value: zZkhKqFjqXR4g5MZCsJUZCnhCcoPyZ
rawRequest:
query: {}
variables: {}
---
kind: LifecyclePluginHook
version: v1
definition:
pre: response
name: cache_set_test
url:
valueFromEnv: HASURA_CACHING_PRE_RESPONSE_URL
config:
request:
headers:
additional:
hasura-m-auth:
value: zZkhKqFjqXR4g5MZCsJUZCnhCcoPyZ
rawRequest:
query: {}
variables: {}
We've used valueFromEnv
so that we can dynamically and securely add values from our environment variables. You can add
these values to your root-level .env
and then map them in the globals
subgraph.yaml file. Alternatively, you can
include raw strings here using value
instead of valueFromEnv
and passing the keys.
For local development, HASURA_CACHING_PRE_PARSE_URL
should be http://local.hasura.dev:8787/pre-parse
, and
HASURA_CACHING_PRE_RESPONSE_URL
should be http://local.hasura.dev:8787/pre-response
.
Running the project
At this point, we can create a build of our project and start local development:
$ ddn supergraph build local
$ ddn run docker-start
Queries marked in the caching config as cacheable should now be cached. The caching plugin will output logs to indicate
which requests have and have not been cached, so docker compose logs -f caching
will allow you to watch these logs as
they arise.
Deploying the plugin
The connector can be deployed as a regular HTTP service, anywhere an Express server can be deployed. When deployed, make
sure to set the HASURA_CACHING_PRE_PARSE_URL
and HASURA_CACHING_PRE_RESPONSE_URL
to appropriate values in
.cloud.env
. Note that the plugin must be visible from your Hasura deployment: if hosting in the Hasura Cloud, the
plugin must be publicly visible. In this instance, make sure to set the hasura-m-auth
header to something other than
the example given in this guide to keep the plugin secure from malicious third-party users.