Skip to main content
Version: 3.17

graphql-proxy-cache

描述#

graphql-proxy-cache 插件为 GraphQL 查询响应提供缓存能力,支持磁盘和内存两种缓存策略,适用于 GETPOST 请求。

缓存键由插件配置版本、路由/服务/Host 标识符以及 GraphQL 请求体共同生成:

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

包含 mutation 操作的请求永远不会被缓存,始终直接透传到上游。

本插件复用 proxy-cache 插件的缓存基础设施。启用本插件前,需要先在 config.yaml 中配置缓存区域。

属性#

名称类型必选项默认值有效值描述
cache_strategystringdisk["disk", "memory"]缓存策略。disk 使用 NGINX 原生 proxy_cache 将响应缓存到磁盘;memory 使用共享内存字典缓存响应。
cache_zonestringdisk_cache_one使用的缓存区域,值必须与静态配置中定义的某个区域名称一致。使用磁盘策略时应指定磁盘缓存区域,使用内存策略时应指定内存缓存区域。
cache_ttlinteger300>= 1内存策略的缓存生存时间(TTL),单位为秒。对于磁盘策略,TTL 由上游响应的 ExpiresCache-Control 头控制;若两者均不存在,则使用 config.yaml 中配置的 cache_ttl
consumer_isolationbooleantruetrue 时,按已认证身份对缓存进行分区。当请求解析为 APISIX 消费者(ctx.consumer_name)或携带 remote user(ctx.var.remote_user)时,身份会作为前缀加入有效缓存键,使每个消费者拥有独立的缓存命名空间。若希望不同消费者共享缓存,可设置为 false
cache_set_cookiebooleanfalsetrue 时,缓存包含 Set-Cookie 响应头的响应。仅对内存策略有效——磁盘策略由 NGINX 原生处理,始终不缓存带 Set-Cookie 的响应。仅当上游的 Set-Cookie 与具体用户无关时才启用。

静态配置#

graphql-proxy-cache 插件复用 config.yaml 中定义的 proxy_cache 缓存区域。启用本插件前,需要至少配置一个缓存区域:

config.yaml
apisix:
proxy_cache:
cache_ttl: 10s # 磁盘缓存时若 Expires/Cache-Control 均不存在时使用的默认 TTL
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

修改后重新加载 APISIX 以使配置生效。

示例#

以下示例演示了如何为不同场景配置 graphql-proxy-cache

note

您可以使用以下命令从 config.yaml 中获取 admin_key 并存入环境变量:

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

缓存 GraphQL 查询#

以下示例演示如何在路由上启用 graphql-proxy-cache,使用默认的磁盘缓存策略:

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"
}'

发送 GraphQL POST 请求:

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

首次请求会产生缓存未命中:

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

再次发送相同请求则会命中缓存:

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

对 Mutation 操作绕过缓存#

graphql-proxy-cache 对包含 mutation 操作的 GraphQL 请求自动绕过缓存:

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

响应中包含 Apisix-Cache-Status: BYPASS,请求直接转发到上游:

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

使用内存缓存#

以下示例启用内存缓存策略,TTL 设置为 60 秒:

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 接口用于缓存失效:

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

其中:

  • :strategydiskmemory
  • :route_id — 路由 ID
  • :cache_key — 响应头 APISIX-Cache-Key 返回的值

首先使用 public-api 插件创建一个路由来暴露清除接口:

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/*"
}'

然后使用之前响应中的缓存键发送清除请求:

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

清除成功返回 HTTP 200,缓存条目不存在则返回 HTTP 404

禁用插件#

从路由配置中移除 graphql-proxy-cache 插件即可禁用:

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
}
}
}'