配置 GraphQL 代理
API7 网关可以像代理其他 HTTP API 一样代理 GraphQL 流量。在支持 GraphQL 感知插件的环境中,你还可以应用 GraphQL 专用 的限流和缓存策略。
前提条件
- API7 企业版实例正在运行。
- 已创建网关组,并且网关实例正在运行。
- Dashboard Token。
基础 GraphQL 代理
从一个标准 HTTP 路由开始,将 GraphQL 请求转发到上游。
以下示例使用 https://countries.trevorblades.com/ 作为上游。代理到期望自身主机名的 HTTPS上游时,请设置 scheme: https 和 pass_host: node。
- ADC
- Admin API
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
adc sync -f adc.yaml
# 1. 为 GraphQL 上游创建服务
curl -k "https://localhost:7443/apisix/admin/services/graphql-service?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "graphql-service",
"upstream": {
"type": "roundrobin",
"scheme": "https",
"pass_host": "node",
"nodes": [
{
"host": "countries.trevorblades.com",
"port": 443,
"weight": 1
}
]
}
}'
# 2. 为该服务创建路由
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"],
"methods": ["POST"],
"service_id": "graphql-service"
}'
在本地验证环境中,基础 Admin API 示例在使用 scheme: https 和 pass_host: node 配置上游后,可以端到端正常工作。
GraphQL 限流
graphql-limit-count插件基于查询深度提供 GraphQL 感知的限流能力。
配置 GraphQL 限流
在代理到 GraphQL 上游的路由上启用 graphql-limit-count 插件。该插件仅支持 POST 方法。
除了 count、time_window、key_type 和 key 外,该插件还需要其他字段。至少需要包含 policy。例如,本地策略使用 policy: local。
- Admin API
- ADC
curl -k "https://localhost:7443/apisix/admin/routes/graphql-limit-route?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "graphql-limit-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"
}
}
}'
services:
- name: graphql-limit-service
upstream:
scheme: https
pass_host: node
nodes:
- host: countries.trevorblades.com
port: 443
weight: 1
routes:
- name: graphql-limit-route
uris:
- /graphql
methods:
- POST
plugins:
graphql-limit-count:
count: 6
time_window: 60
rejected_code: 429
policy: local
key_type: var
key: remote_addr
adc sync -f adc.yaml
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。
- Admin API
- ADC
curl -k "https://localhost:7443/apisix/admin/routes/graphql-cache-route?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "graphql-cache-route",
"paths": ["/graphql"],
"service_id": "graphql-service",
"methods": ["POST"],
"plugins": {
"graphql-proxy-cache": {}
}
}'
services:
- name: graphql-cache-service
upstream:
scheme: https
pass_host: node
nodes:
- host: countries.trevorblades.com
port: 443
weight: 1
routes:
- name: graphql-cache-route
uris:
- /graphql
methods:
- POST
plugins:
graphql-proxy-cache: {}
adc sync -f adc.yaml
清理缓存
你可以向插件的控制端点发送 DELETE 请求,以清理特定 GraphQL 查询的缓存。
curl -X DELETE http://localhost:9080/apisix/plugin/graphql-proxy-cache/*
验证配置
你可以发送带有 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"}]}}
如果启用了 count: 6 的 graphql-limit-count,并重复以下查询四次,前三个请求应成功,第四个请求应返回 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-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。
后续步骤
- 配置限流 — 探索更高级的限流策略。
- 配置代理缓存 — 了解标准 HTTP 缓存。
- 配置 gRPC 代理 — 处理 gRPC 服务和转码。
- 配置 WebSocket 代理 — 管理实时双向通信。