degraphql
The degraphql plugin supports communicating with upstream GraphQL services over regular HTTP requests by mapping GraphQL queries to HTTP endpoints.
Examples
The examples below use Pokemon GraphQL API as the upstream GraphQL server and demonstrate how you can configure degraphql to transform different types of GraphQL queries.
Transform a Basic Query
The following example demonstrates how you can transform a simple query below:
query {
getAllPokemon {
key
color
}
}
- Admin API
- ADC
- Ingress Controller
Create a route with the degraphql plugin as follows:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "degraphql-route",
"methods": ["POST"],
"uri": "/v8",
"upstream": {
"type": "roundrobin",
"nodes": {
"graphqlpokemon.favware.tech": 1
},
"scheme": "https",
"pass_host": "node"
},
"plugins": {
"degraphql": {
"query": "{\n getAllPokemon {\n key\n color\n }\n}"
}
}
}'
Create a route with the degraphql plugin as follows:
services:
- name: degraphql-service
routes:
- name: degraphql-route
methods:
- POST
uris:
- /v8
plugins:
degraphql:
query: |
{
getAllPokemon {
key
color
}
}
upstream:
type: roundrobin
nodes:
- host: graphqlpokemon.favware.tech
port: 443
weight: 1
scheme: https
Synchronize the configuration to the gateway:
adc sync -f adc.yaml
- Gateway API
- APISIX CRD
Gateway API currently has a bug where the upstream scheme is not correctly configured. As a result, requests are forwarded over HTTP instead of HTTPS, which leads to the error The plain HTTP request was sent to HTTPS port.
This issue is scheduled to be fixed in APISIX Ingress Controller version 2.0.2 and will also be addressed in API7 Ingress Controller in an upcoming release. Until then, this example cannot be completed using Gateway API.
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: degraphql-route
spec:
ingressClassName: apisix
http:
- name: degraphql-route
match:
paths:
- /v8
methods:
- POST
upstreams:
- name: graphql-pokemon
plugins:
- name: degraphql
enable: true
config:
query: |
{
getAllPokemon {
key
color
}
}
---
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: aic
name: graphql-pokemon
spec:
ingressClassName: apisix
externalNodes:
- type: Domain
name: graphqlpokemon.favware.tech
port: 443
scheme: https
passHost: node
Apply the configuration to your cluster:
kubectl apply -f degraphql-ic.yaml
Send a request to the route to verify:
curl "http://127.0.0.1:9080/v8" -X POST
You should see a response similar to the following:
{
"data": {
"getAllPokemon": [
{ "key": "pokestarsmeargle", "color": "White" },
{ "key": "pokestarufo", "color": "White" },
{ "key": "pokestarufo2", "color": "White" },
...
{ "key": "terapagosstellar", "color": "Blue" },
{ "key": "pecharunt", "color": "Purple" }
]
}
}
Transform a Query with Variables
The following example demonstrates how you can transform the query below, with a variable:
query ($pokemon: PokemonEnum!) {
getPokemon(
pokemon: $pokemon
) {
color
species
}
}
variable:
{
"pokemon": "pikachu"
}
- Admin API
- ADC
- Ingress Controller
Create a route with the degraphql plugin as follows:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "degraphql-route",
"uri": "/v8",
"upstream": {
"type": "roundrobin",
"nodes": {
"graphqlpokemon.favware.tech": 1
},
"scheme": "https",
"pass_host": "node"
},
"plugins": {
"degraphql": {
"query": "query ($pokemon: PokemonEnum!) {\n getPokemon(\n pokemon: $pokemon\n ) {\n color\n species\n }\n}\n",
"variables": ["pokemon"]
}
}
}'
Create a route with the degraphql plugin as follows:
services:
- name: degraphql-service
routes:
- name: degraphql-route
uris:
- /v8
plugins:
degraphql:
query: |
query ($pokemon: PokemonEnum!) {
getPokemon(
pokemon: $pokemon
) {
color
species
}
}
variables:
- pokemon
upstream:
type: roundrobin
nodes:
- host: graphqlpokemon.favware.tech
port: 443
weight: 1
scheme: https
Synchronize the configuration to the gateway:
adc sync -f adc.yaml
- Gateway API
- APISIX CRD
Gateway API currently has a bug where the upstream scheme is not correctly configured. As a result, requests are forwarded over HTTP instead of HTTPS, which leads to the error The plain HTTP request was sent to HTTPS port.
This issue is scheduled to be fixed in APISIX Ingress Controller version 2.0.2 and will also be addressed in API7 Ingress Controller in an upcoming release. Until then, this example cannot be completed using Gateway API.
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: degraphql-route
spec:
ingressClassName: apisix
http:
- name: degraphql-route
match:
paths:
- /v8
upstreams:
- name: graphql-pokemon
plugins:
- name: degraphql
enable: true
config:
query: |
query ($pokemon: PokemonEnum!) {
getPokemon(
pokemon: $pokemon
) {
color
species
}
}
variables:
- pokemon
---
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: aic
name: graphql-pokemon
spec:
ingressClassName: apisix
externalNodes:
- type: Domain
name: graphqlpokemon.favware.tech
port: 443
scheme: https
passHost: node
Apply the configuration to your cluster:
kubectl apply -f degraphql-ic.yaml
Send a request to the route to verify:
curl "http://127.0.0.1:9080/v8" -X POST \
-d '{
"pokemon": "pikachu"
}'
You should see a response similar to the following:
{
"data": {
"getPokemon": {
"color": "Yellow",
"species": "pikachu"
}
}
}
Alternatively, you can also pass the variable in the URL query string of a GET request:
curl "http://127.0.0.1:9080/v8?pokemon=pikachu" -H "x-apollo-operation-name: GET"
You should see the same response as the previous.