Configure GraphQL Proxying
API7 Gateway can proxy GraphQL traffic like any other HTTP API. In environments where the GraphQL-aware plugins are available, you can also apply GraphQL-specific rate limiting and caching policies.
Prerequisites
- An API7 Enterprise instance is running.
- A Gateway Group is created and a Gateway instance is running.
- A token from the Dashboard.
Basic GraphQL Proxying
Start with a standard HTTP route that forwards GraphQL requests to the upstream.
The following examples use https://countries.trevorblades.com/ as an upstream. When proxying to an HTTPS upstream that expects its own hostname, set scheme: https and 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. Create a Service for the GraphQL upstream
curl -k "https://localhost:7443/apisix/admin/services/graphql-service?gateway_group_id={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. Create a Route for the Service
curl -k "https://localhost:7443/apisix/admin/routes/graphql-route?gateway_group_id={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"
}'
In the local validation environment, the basic Admin API example worked end to end after configuring the upstream with scheme: https and pass_host: node.
GraphQL Rate Limiting
The graphql-limit-count plugin provides GraphQL-aware rate limiting based on query depth.
Configure GraphQL Rate Limiting
Enable the graphql-limit-count plugin on a route that proxies to your GraphQL upstream. This plugin only supports the POST method.
This plugin requires additional fields beyond count, time_window, key_type, and key. At minimum, include policy. For example, the local policy uses policy: local.
- Admin API
- ADC
curl -k "https://localhost:7443/apisix/admin/routes/graphql-limit-route?gateway_group_id={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 Caching
The graphql-proxy-cache plugin provides GraphQL-aware caching for query operations while bypassing mutations.
Configure GraphQL Caching
Enable the graphql-proxy-cache plugin on your route.
In the local validation environment, both GraphQL-aware plugin configurations were validated end to end. graphql-limit-count returned 429 after the configured quota was exceeded, and graphql-proxy-cache returned Apisix-Cache-Status: MISS on the first request and Apisix-Cache-Status: HIT on the second identical request.
- Admin API
- ADC
curl -k "https://localhost:7443/apisix/admin/routes/graphql-cache-route?gateway_group_id={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
Purge Cache
You can purge the cache for a specific GraphQL query by sending a DELETE request to the plugin's control endpoint.
curl -X DELETE http://localhost:9080/apisix/plugin/graphql-proxy-cache/*
Validate the Configuration
You can test the basic GraphQL proxying by sending a POST request with a GraphQL query.
curl -X POST http://localhost:9080/graphql \
-H "Content-Type: application/json" \
-d '{"query": "query { countries { code } }"}'
The gateway proxies the GraphQL request and returns the response from the upstream:
{"data":{"countries":[{"code":"AD"},{"code":"AE"}]}}
If graphql-limit-count is enabled with count: 6 and you repeat the following query four times, the first three requests should succeed and the fourth should return 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
If graphql-proxy-cache is enabled, repeat the same query twice and confirm the cache status headers:
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 } }"}'
The first response should include Apisix-Cache-Status: MISS and the second should include Apisix-Cache-Status: HIT.
Next Steps
- Configure Rate Limiting — explore more advanced rate limiting strategies.
- Configure Proxy Caching — learn about standard HTTP caching.
- Configure gRPC Proxying — handle gRPC services and transcoding.
- Configure WebSocket Proxying — manage real-time, bidirectional communication.