Docs
Plugin HubOverview

degraphql

The degraphql plugin maps an HTTP route to a predefined GraphQL query. Clients can call the route without constructing a GraphQL document, while the plugin sends the configured query and selected request values to the upstream GraphQL service.

For POST requests, configured variables come from a JSON request body. For GET requests, they come from URL query parameters.

Examples

The examples use the maintained Pokémon GraphQL API at https://graphqlpokemon.favware.tech/v8. The first example sends a fixed query, and the second updates the same route to accept a variable.

Send a Fixed Query

The route sends this query whenever it receives a POST request:

{
  getPokemon(pokemon: pikachu) {
    key
    color
    species
  }
}

Create the route:

curl "http://127.0.0.1:9180/apisix/admin/routes/degraphql-pokemon" -X PUT \
  -H "X-API-KEY: ${ADMIN_API_KEY}" \
  -d '{
    "uri": "/v8",
    "methods": ["POST"],
    "plugins": {
      "degraphql": {
        "query": "{\n  getPokemon(pokemon: pikachu) {\n    key\n    color\n    species\n  }\n}"
      }
    },
    "upstream": {
      "type": "roundrobin",
      "nodes": {
        "graphqlpokemon.favware.tech:443": 1
      },
      "scheme": "https",
      "pass_host": "node"
    }
  }'

Send a POST request without a GraphQL body:

curl "http://127.0.0.1:9080/v8" -X POST

The response should contain the selected Pokémon fields:

{
  "data": {
    "getPokemon": {
      "key": "pikachu",
      "color": "Yellow",
      "species": "pikachu"
    }
  }
}

Pass a Variable

Update the route to use a GraphQL variable named pokemon:

query ($pokemon: PokemonEnum!) {
  getPokemon(pokemon: $pokemon) {
    key
    color
    species
  }
}
curl "http://127.0.0.1:9180/apisix/admin/routes/degraphql-pokemon" -X PUT \
  -H "X-API-KEY: ${ADMIN_API_KEY}" \
  -d '{
    "uri": "/v8",
    "methods": ["GET", "POST"],
    "plugins": {
      "degraphql": {
        "query": "query ($pokemon: PokemonEnum!) {\n  getPokemon(pokemon: $pokemon) {\n    key\n    color\n    species\n  }\n}",
        "variables": ["pokemon"]
      }
    },
    "upstream": {
      "type": "roundrobin",
      "nodes": {
        "graphqlpokemon.favware.tech:443": 1
      },
      "scheme": "https",
      "pass_host": "node"
    }
  }'

For a POST request, provide the configured variable in a JSON body:

curl "http://127.0.0.1:9080/v8" -X POST \
  -H "Content-Type: application/json" \
  -d '{
    "pokemon": "pikachu"
  }'

The response should contain the requested Pokémon:

{
  "data": {
    "getPokemon": {
      "key": "pikachu",
      "color": "Yellow",
      "species": "pikachu"
    }
  }
}

For a GET request, provide the variable as a URL query parameter:

curl "http://127.0.0.1:9080/v8?pokemon=pikachu" \
  -H "x-apollo-operation-name: GET"

The Pokémon API uses Apollo Server CSRF prevention and requires the x-apollo-operation-name header for GET requests. This requirement comes from the upstream API, not from degraphql. The response should match the POST result.