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

API7 网关 AI Agent Skill:recipe graphql proxy

本页提供 recipe graphql proxy 场景的 API7 企业版操作指南。请保留下方命令、字段、配置项和 API 路径的原样,并根据实际网关环境替换示例值。

Overview

API7 EE can route and protect GraphQL traffic by using GraphQL variables from the parsed request body:

  • graphql_name: operation name, such as getUser.
  • graphql_operation: operation type, such as query or mutation.
  • graphql_root_fields: top-level fields requested by the operation.

Use the current a7 service-backed route model:

  1. Create services for the GraphQL backends.
  2. Create routes with paths and service_id.
  3. Add GraphQL vars and plugins through a7 route create/update -f payloads.

When to Use

  • Route read-only GraphQL queries and mutations to different backends.
  • Apply tighter limits to expensive operations.
  • Expose REST-style paths that are translated to GraphQL with degraphql.
  • Protect sensitive GraphQL operations with auth and access-control plugins.

Approach A: Operation-Based Routing

Create separate services for read and write GraphQL traffic.

a7 service create -g prod-group -f - <<'EOF'
{
"id": "gql-read-service",
"name": "gql-read-service",
"upstream": {
"type": "roundrobin",
"nodes": [
{"host": "gql-read-replica", "port": 4000, "weight": 1}
]
}
}
EOF

a7 service create -g prod-group -f - <<'EOF'
{
"id": "gql-write-service",
"name": "gql-write-service",
"upstream": {
"type": "roundrobin",
"nodes": [
{"host": "gql-primary-db", "port": 4000, "weight": 1}
]
}
}
EOF

Route GraphQL queries to the read service:

a7 route create -g prod-group -f - <<'EOF'
{
"id": "gql-queries",
"name": "gql-queries",
"paths": ["/graphql"],
"service_id": "gql-read-service",
"vars": [["graphql_operation", "==", "query"]]
}
EOF

Route GraphQL mutations to the write service:

a7 route create -g prod-group -f - <<'EOF'
{
"id": "gql-mutations",
"name": "gql-mutations",
"paths": ["/graphql"],
"service_id": "gql-write-service",
"vars": [["graphql_operation", "==", "mutation"]]
}
EOF

Use route priorities if a generic /graphql route overlaps with more specific GraphQL operation routes.

Approach B: Per-Operation Rate Limiting

Apply stricter limits to mutation traffic. Include the service_id in update payloads so the route remains bound to the intended service.

a7 route update gql-mutations -g prod-group -f - <<'EOF'
{
"service_id": "gql-write-service",
"plugins": {
"key-auth": {},
"limit-count": {
"count": 50,
"time_window": 60,
"key_type": "var",
"key": "consumer_name",
"rejected_code": 429,
"rejected_msg": "Mutation quota exceeded"
}
}
}
EOF

Create consumers and credentials separately:

a7 consumer create -g prod-group --username frontend-app
a7 credential create -g prod-group --consumer frontend-app --plugins-json '{"key-auth":{"key":"frontend-secret"}}'

Approach C: REST-to-GraphQL with degraphql

The degraphql plugin maps a REST-style path to a GraphQL query on the backend.

a7 service create -g prod-group -f - <<'EOF'
{
"id": "graphql-engine-service",
"name": "graphql-engine-service",
"upstream": {
"type": "roundrobin",
"nodes": [
{"host": "graphql-engine", "port": 8080, "weight": 1}
]
}
}
EOF

a7 route create -g prod-group -f - <<'EOF'
{
"id": "rest-bridge-user",
"name": "rest-bridge-user",
"paths": ["/api/users/:id"],
"methods": ["GET"],
"service_id": "graphql-engine-service",
"plugins": {
"degraphql": {
"query": "query getUser($id: ID!) { user(id: $id) { name email profile { bio } } }",
"variables": ["id"]
}
}
}
EOF

Approach D: Restrict Mutations

Use consumer-restriction to limit mutation routes to selected consumers or consumer groups.

a7 route update gql-mutations -g prod-group -f - <<'EOF'
{
"service_id": "gql-write-service",
"plugins": {
"key-auth": {},
"consumer-restriction": {
"type": "consumer_name",
"whitelist": ["admin-client", "system-client"],
"rejected_code": 403,
"rejected_msg": "Only approved clients can perform mutations"
}
}
}
EOF

Declarative Management Notes

a7 config sync can manage services and normal service-backed routes. GraphQL operation matching currently requires raw route payload fields such as vars, so use a7 route create/update -f for those operation-specific routes.

version: "1"
services:
- id: graphql-engine-service
name: graphql-engine-service
upstream:
type: roundrobin
nodes:
- host: graphql-engine
port: 8080
weight: 1
routes:
- id: rest-bridge-user
name: rest-bridge-user
paths:
- /api/users/:id
methods:
- GET
service_id: graphql-engine-service
plugins:
degraphql:
query: "query getUser($id: ID!) { user(id: $id) { name email profile { bio } } }"
variables:
- id

Apply it to one gateway group:

a7 config sync -g prod-group -f graphql-rest-bridge.yaml

Verification

a7 service get gql-read-service -g prod-group -o json
a7 route get gql-queries -g prod-group -o json
a7 route get gql-mutations -g prod-group -o json

Traffic verification requires a deployed gateway and GraphQL backend:

curl -X POST https://gateway.prod.example.com/graphql \
-H "Content-Type: application/json" \
-H "apikey: frontend-secret" \
-d '{"query": "query getUser { user(id: 1) { name } }"}'

curl -X POST https://gateway.prod.example.com/graphql \
-H "Content-Type: application/json" \
-H "apikey: frontend-secret" \
-d '{"query": "mutation deleteUser { deleteUser(id: 1) { success } }"}'

Important Considerations

  • Body parsing is required for GraphQL variables to be available.
  • Batched requests may only expose variables for the first operation.
  • Use route priorities when multiple routes share /graphql.
  • Keep auth credentials under a7 credential, not embedded directly in the consumer.

This page is generated from a7-recipe-graphql-proxy/SKILL.md in the api7/a7 repository. Browse all skills on the AI Agent Skills page.