Skip to main content
Version: 3.17

graphql-proxy-cache

Description#

The graphql-proxy-cache Plugin provides caching for GraphQL query responses. It supports both disk-based and memory-based caching strategies for GET and POST requests.

The cache key is derived from the plugin configuration version, route/service/host identifiers, and the GraphQL query body:

key = md5(conf_version + host + route_id + service_id + identity + body)

Requests containing mutation operations are never cached — they always bypass the cache and reach the upstream directly.

The Plugin reuses the caching infrastructure of the proxy-cache Plugin. Cache zones must be configured in config.yaml before enabling this Plugin.

Attributes#

NameTypeRequiredDefaultValid valuesDescription
cache_strategystringFalsedisk["disk", "memory"]Caching strategy. Use disk to cache responses on disk (via NGINX's native proxy_cache), or memory to cache in a shared memory dictionary.
cache_zonestringFalsedisk_cache_oneCache zone to use. The value must match one of the zones defined in the static configurations. Use a disk zone with the disk strategy and a memory zone with the memory strategy.
cache_ttlintegerFalse300>= 1Cache time to live (TTL) in seconds for the memory strategy. For the disk strategy, TTL is controlled by the upstream Expires or Cache-Control response headers; if neither is present, the cache_ttl configured in config.yaml is used.
consumer_isolationbooleanFalsetrueIf true, partition the cache by authenticated identity. When the request resolves to an APISIX consumer (ctx.consumer_name) or carries a remote user (ctx.var.remote_user), the identity is prepended to the effective cache key so each consumer gets its own cache namespace. Set to false if you want different consumers to share cached responses.
cache_set_cookiebooleanFalsefalseIf true, cache responses that include a Set-Cookie header. Only valid for the memory strategy — the disk strategy never caches responses with Set-Cookie (NGINX enforces this). Enable only when the upstream's Set-Cookie is not user-specific.

Static Configurations#

The graphql-proxy-cache Plugin reuses the proxy_cache zones defined in config.yaml. Configure at least one cache zone before enabling this Plugin:

config.yaml
apisix:
proxy_cache:
cache_ttl: 10s # default TTL for disk cache when Expires/Cache-Control are absent
zones:
- name: disk_cache_one
memory_size: 50m
disk_size: 1G
disk_path: /tmp/disk_cache_one
cache_levels: 1:2
- name: memory_cache
memory_size: 50m

Reload APISIX for changes to take effect.

Examples#

The examples below demonstrate how you can configure graphql-proxy-cache for different scenarios.

note

You can fetch the admin_key from config.yaml and save it to an environment variable with the following command:

admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g')

Cache GraphQL Queries#

The following example shows how to enable graphql-proxy-cache on a route with the default disk strategy:

curl http://127.0.0.1:9180/apisix/admin/routes/1 \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"plugins": {
"graphql-proxy-cache": {}
},
"upstream": {
"nodes": {
"127.0.0.1:8080": 1
},
"type": "roundrobin"
},
"uri": "/graphql"
}'

Send a GraphQL POST request:

curl http://127.0.0.1:9080/graphql \
-H "Content-Type: application/json" \
-d '{"query": "query { persons { name } }"}'

The first request results in a cache miss:

HTTP/1.1 200 OK
Apisix-Cache-Status: MISS
APISIX-Cache-Key: <cache-key>

Sending the same request again returns a cache hit:

HTTP/1.1 200 OK
Apisix-Cache-Status: HIT
APISIX-Cache-Key: <cache-key>

Bypass Cache for Mutation Operations#

graphql-proxy-cache automatically bypasses the cache for GraphQL requests containing mutation operations:

curl http://127.0.0.1:9080/graphql \
-H "Content-Type: application/json" \
-d '{"query": "mutation { addPerson(name: \"Alice\") { id } }"}'

The response includes Apisix-Cache-Status: BYPASS, and the request is forwarded directly to the upstream:

HTTP/1.1 200 OK
Apisix-Cache-Status: BYPASS

Use In-Memory Cache#

The following example enables the memory strategy with a 60-second TTL:

curl http://127.0.0.1:9180/apisix/admin/routes/1 \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"plugins": {
"graphql-proxy-cache": {
"cache_strategy": "memory",
"cache_zone": "memory_cache",
"cache_ttl": 60
}
},
"upstream": {
"nodes": {
"127.0.0.1:8080": 1
},
"type": "roundrobin"
},
"uri": "/graphql"
}'

Purge Cached Responses#

The Plugin exposes a PURGE endpoint for cache invalidation:

PURGE /apisix/plugin/graphql-proxy-cache/:strategy/:route_id/:cache_key

Where:

  • :strategydisk or memory
  • :route_id — the ID of the route
  • :cache_key — the value returned in the APISIX-Cache-Key response header

To expose the purge endpoint, create a route using the public-api Plugin:

curl http://127.0.0.1:9180/apisix/admin/routes/graphql-cache-purge \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"plugins": {
"public-api": {}
},
"uri": "/apisix/plugin/graphql-proxy-cache/*"
}'

Then send a purge request using the cache key from a previous response:

curl http://127.0.0.1:9080/apisix/plugin/graphql-proxy-cache/disk/1/<cache-key> \
-X PURGE

A successful purge returns HTTP 200. If the cache entry does not exist, HTTP 404 is returned.

Disable Plugin#

To disable the graphql-proxy-cache Plugin, remove it from the route configuration:

curl http://127.0.0.1:9180/apisix/admin/routes/1 \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"uri": "/graphql",
"plugins": {},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:8080": 1
}
}
}'