API7 Docs
API7 GatewayHow-To GuidesProtocol ProxyConfigure GraphQL Proxying

Configure GraphQL Proxying

Learn how to proxy GraphQL APIs through API7 Gateway and when to add GraphQL-aware plugins for rate limiting and caching.

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.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
adc sync -f adc.yaml

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.

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

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.

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

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