跳到主要内容
版本:3.9.x

配置 GraphQL 代理

API7 网关可以像代理其他 HTTP API 一样代理 GraphQL 流量。在支持 GraphQL 感知插件的环境中,你还可以应用 GraphQL 专用的限流和缓存策略。

前置条件​

  • API7 企业版实例正在运行。
  • 已创建网关组,并且网关实例正在运行。
  • 从控制台获取 Token。

基础 GraphQL 代理​

从一个标准 HTTP 路由开始,将 GraphQL 请求转发到上游。

以下示例使用 https://countries.trevorblades.com/ 作为上游。代理到要求使用自身主机名的 HTTPS 上游时,请设置 scheme: https 和 pass_host: node。

adc.yaml
services:
- name: graphql-service
upstream:
scheme: https
pass_host: node
nodes:
- host: countries.trevorblades.com
port: 443
weight: 1
routes:
- name: graphql-route
uris:
- /graphql
methods:
- POST
labels:
docs-example: graphql-service

预览本示例管理的资源变更,确认没有非预期的更新或删除:

adc diff -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=graphql-service

审查变更后同步配置:

adc sync -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=graphql-service

在本地验证环境中,基础 Admin API 示例在使用 scheme: https 和 pass_host: node 配置上游后,可以端到端正常工作。

以下场景会更新同一个服务和路由。请先验证限流,再应用缓存场景,因为缓存配置会以 graphql-proxy-cache 替换 graphql-limit-count。

GraphQL 限流​

graphql-limit-count 插件基于查询深度提供 GraphQL 感知的限流能力。

配置 GraphQL 限流​

更新已有路由以启用 graphql-limit-count 插件。该插件仅支持 POST 方法。

除了 count、time_window、key_type 和 key 外,该插件还需要其他字段。至少需要包含 policy。例如,本地策略使用 policy: local。

curl -k "https://localhost:7443/apisix/admin/routes/graphql-route?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "graphql-route",
"paths": ["/graphql"],
"service_id": "graphql-service",
"methods": ["POST"],
"plugins": {
"graphql-limit-count": {
"count": 6,
"time_window": 60,
"rejected_code": 429,
"policy": "local",
"key_type": "var",
"key": "remote_addr"
}
}
}'

重复发送以下查询四次。前三次请求应成功,第四次应返回 429 Too Many Requests:

for i in $(seq 1 4); do
curl -s -o /dev/null -w '%{http_code}\n' "http://localhost:9080/graphql" \
-H "Content-Type: application/json" \
-d '{"query":"query { continents { code } }"}'
done

GraphQL 缓存​

graphql-proxy-cache 插件可为查询操作提供 GraphQL 感知的缓存,变更操作(mutation)不参与缓存。

配置 GraphQL 缓存​

更新同一路由,用 graphql-proxy-cache 替换限流插件配置。

在本地验证环境中,两个 GraphQL 感知插件配置分别完成了端到端验证。graphql-limit-count 在超过配置额度后返回 429;graphql-proxy-cache 在首次请求时返回 Apisix-Cache-Status: MISS,在第二次相同请求时返回 Apisix-Cache-Status: HIT。

curl -k "https://localhost:7443/apisix/admin/routes/graphql-route?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "graphql-route",
"paths": ["/graphql"],
"service_id": "graphql-service",
"methods": ["POST"],
"plugins": {
"graphql-proxy-cache": {}
}
}'

清理缓存​

上面的示例只启用了 graphql-proxy-cache,尚未配置受保护的缓存清理路由,因此不能直接通过该路由清理单条缓存。需要清理磁盘缓存条目时,请参考上方插件参考中“清除磁盘缓存条目”的做法:配置带 public-api 和 key-auth 的受保护路由,取得缓存路由 ID 与缓存键,再向 /apisix/plugin/graphql-proxy-cache/disk/${CACHE_ROUTE_ID}/${CACHE_KEY} 发送带 API Key 的 PURGE 请求。Plugin Hub 示例使用 Apache APISIX 的 9180 Admin API;在 API7 网关 3.9 中须按本页的 7443 Admin API 和网关组范围调整配置,不能直接照搬该命令。不要把通配路由 * 当作某条查询的缓存键。

验证配置​

你可以发送带有 GraphQL 查询的 POST 请求来测试基础 GraphQL 代理。

curl -X POST "http://localhost:9080/graphql" \
-H "Content-Type: application/json" \
-d '{"query": "query { countries { code } }"}'

网关会代理 GraphQL 请求,并返回来自上游的响应:

{"data":{"countries":[{"code":"AD"},{"code":"AE"}]}}

如果启用了 graphql-proxy-cache,请重复相同查询两次并确认缓存状态响应头:

curl -i -X POST "http://localhost:9080/graphql" \
-H "Content-Type: application/json" \
-d '{"query":"query { continents { code } }"}'

curl -i -X POST "http://localhost:9080/graphql" \
-H "Content-Type: application/json" \
-d '{"query":"query { continents { code } }"}'

第一个响应应包含 Apisix-Cache-Status: MISS,第二个响应应包含 Apisix-Cache-Status: HIT。

后续步骤​