Document updated on Nov 3, 2021
Encoding | no-op skips this configuration |
---|---|
Since | v2.0 |
Namespace | backend/graphql |
Scope | backend |
Source | luraproject/lura |
The GraphQL integration allows you to work in two different modes:
KrakenD offers a simple yet powerful way of consuming GraphQL content from your distributed graphs. The main benefits of using KrakenD as a GraphQL Gateway are:
In this scenario, the end-user consumes traditional REST content, without even knowing that there is a GraphQL server behind:
KrakenD can use the variables in the body or in the endpoint URL to generate the final GraphQL query that will be sent to the GraphQL server. The query is loaded from an external file or declared inline in the configuration and contains any variables needing replacement with the user input.
KrakenD acts as the GraphQL client, negotiating with the GraphQL server the content and hiding its complexity to the end-user. The end-user consumes REST content and retrieves the data in JSON, XML, RSS, or any other format supported by KrakenD.
The configuration to consume GraphQL content from your GrapQL graphs could look like this:
{
"endpoint": "/marketing/{user_id}",
"method": "POST",
"backend": [
{
"timeout": "4100ms",
"url_pattern": "/graphql?timeout=4s",
"extra_config": {
"backend/graphql": {
"type": "mutation",
"query_path": "./graphql/mutations/marketing.graphql",
"variables": {
"user":"{user_id}",
"other_static_variables": {
"foo": false,
"bar": true
}
},
"operationName": "addMktPreferencesForUser"
}
}
}
]
}
The configuration for the namespace backend/graphql
has the following structure:
*
Required one of:
type
+
query
, or
type
+
query_path
| A meaningful and explicit name for your operation, required in multi-operation documents and for helpful debugging and server-side logging. Example: "addMktPreferencesForUser" |
| An inline GraphQL query you want to send to the server. Use this attribute for simple and inline queries, use query_path instead for larger queries. Use escaping when needed.Example: "{ \n find_follower(func: uid(\"0x3\")) {\n name \n }\n }" |
| Path to the file containing the query. This file is loaded during startup and never checked again, if it changes KrakenD will be unaware of it. Example: "./graphql/mutations/marketing.graphql" |
| The type of query you are declaring, query (read), or mutation (write).Possible values are: "query" , "mutation" |
| A dictionary defining all the variables sent to the GraphQL server. You can use {placeholders} to inject parameters from the endpoint URL. |
Schema: https://www.krakend.io/schema/v2.2/backend/graphql.json
* indicates a required field.
When using an inline query
(as opposed to using a file from the query_path
which does this job automatically), make sure to use escaping when needed. Examples:
- "query": "{ \n find_follower(func: uid(\"0x3\")) {\n name \n }\n }"
.
- "query": "{ q(func: uid(1)) { uid } }"
The combination of type
and the endpoint/backend method
has the following behavior:
GET
: The query to the GQL server uses an autogenerated query string and can contain variables from the URL parameters OR the request body.method=GET
+ type=query
: Generates a query string using any {variables}
in the endpoint, but you don’t have any data in a possible body.method=GET
+ type=mutation
: Generates a query string including any variables in the body of the REST call (if present), but you cannot have {variables}
from the URLPOST
: The query to the GQL server uses an autogenerated body containing all the variables of the URL parameters OR the request body. When the user and the KrakenD configuration define the same variables (collision) the user variables take preference.method=POST
+ type=query
: Generates a body using any {variables}
in the endpoint, but it does not use the body of the user to form the new body.method=POST
+ type=mutation
: Generates a body including any variables in the REST body plus the ones in the configuration, but you cannot have {variables}
from the URLSummarizing in a table:
method=POST | method=GET | |
---|---|---|
Type=query | Query string from user body | Query string from URL {params} |
Type=mutation | Body from user body | Body from URL {params} |
Suppose the end-user makes the following request to KrakenD, which contains a body with a JSON containing campaign
information to /marketing/abcdef
:
$curl -XPOST -d '{"campaign": "xmas"}' http://krakend/marketing/abcdef
With the example and the configuration of KrakenD above, KrakenD combines the variables you have defined in the configuration with the ones sent in the request and the GraphQL server receives a body like the following:
{
"query": "{\n find_follower(func: uid(\"0x3\")) {\n name \n }\n }\n",
"variables": {
"user_id":"{user_id}",
"other_static_variables": {
"foo": false,
"bar": true
},
"campaign": "xmas"
}
}
query
contains the content of the external file defining the GraphQL you want to execute.variables
section contains:user_id
does not replace the value of {user_id}
, as it is a POST + mutationother_static_variables
object is passed as it is in the configuration.campaign
variable is used because the POST has data, and included in the final body, which is also passed to the GraphQL server.In case the method is a GET, instead of a body, the server receives all the data URL-encoded as a query string. For instance:
$curl -XGET http://krakend/marketing/abcdef
In this case the GraphQL server receives a query string with all the contents:
query=%7B%0A++find_follower%28func%3A+uid%28%220x3%22%29%29+%7B%0A++++name+%0A++++%7D%0A++%7D%0A&variables=%7B%22campaing%22%3A%22xmas%22%2C%22other_static_variables%22%3A%7B%22bar%22%3Atrue%2C%22foo%22%3Afalse%7D%2C%22user_id%22%3A%22%7Buser_id%7D%22%7D
{user_id}
is replaced by its value abcdef
other_static_variables
object is passed as it is in the configuration.$curl -XPOST -d '{"campaign": "xmas"}' http://krakend/marketing/abcdef
The GraphQL receives a body with the following content:
{
"query": "{\n find_follower(func: uid(\"0x3\")) {\n name \n }\n }\n",
"variables": {
"other_static_variables": {
"bar": true,
"foo": false
},
"user_id": "abcdef"
}
}
{user_id}
is replaced by its value abcdef
other_static_variables
object is passed as it is in the configuration.campaign
data is not present as a query only accepts data from the URL. Anything else in the body is ignored.The final example of GET + query:
$curl -XGET http://krakend/marketing/abcdef
The GraphQL receives a query string with the following content:
query=%7B%0A++find_follower%28func%3A+uid%28%220x3%22%29%29+%7B%0A++++name+%0A++++%7D%0A++%7D%0A&variables=%7B%22other_static_variables%22%3A%7B%22bar%22%3Atrue%2C%22foo%22%3Afalse%7D%2C%22user_id%22%3A%22abcdef%22%7D
{user_id}
is replaced by its value abcdef
other_static_variables
object is passed as it is in the configuration.In this approach, KrakenD gets in the middle to validate or rate limit requests, but the request is forwarded to the GraphQL servers, who receive the original GraphQL query from the end-user.
When working in this mode, all you need to do is to configure the GraphQL endpoint, and add as the backend your GraphQL. An example:
{
"endpoint": "/graphql",
"input_query_strings":[
"query",
"operationName",
"variables"
],
"backend": [
{
"timeout": "4100ms",
"host": ["http://your-graphql.server:4000"],
"url_pattern": "/graphql?timeout=4s"
}
]
}
The previous example uses a set of recognized query strings to pass to the GraphQL server. You can also use "input_query_strings":["*"]
to forward any query string. The exact configuration works with a POST
method.
As the configuration above is not using no-op
, you can take the opportunity to connect to more servers in the same endpoint by adding additional backend objects in the configuration.
KrakenD’s principles are working with simultaneous aggregation of data. In that sense, consuming multiple subgraphs (or back-end services) comes naturally. However, using the REST to GraphQL capabilities, you can federate data using a simple strategy: define the subgraphs in the configuration instead of moving this responsibility to the consumer.
It is a simplistic approach but still very powerful, as you can define templates with queries and let krakend do the aggregation of the responses.
Create rest endpoints with fixed graphs you’d like to consume in the configuration. Then, in each back-end query (subgraph), you decide what transformation rules to apply, the validation, rate-limiting, etc., and even connect your endpoints with other services like queues.
The following example is a REST endpoint consuming data from 2 different subgraphs in parallel. You could add here any other KrakenD components you could need:
{
"endpoint": "/user-data/{id_user}",
"backend": [
{
"timeout": "3100ms",
"url_pattern": "/graphql?timeout=3s",
"group": "user",
"method": "GET",
"host": ["http://user-graph:4000"],
"extra_config": {
"backend/graphql": {
"type": "query",
"query_path": "./graphql/queries/user.graphql",
"variables": {
"user":"{user_id}"
},
"operationName": "getUserData"
}
}
},
{
"timeout": "2100ms",
"url_pattern": "/graphql?timeout=2s",
"group": "user_metadata",
"method": "GET",
"host": ["http://metadata:4000"],
"extra_config": {
"backend/graphql": {
"type": "query",
"query_path": "./graphql/queries/user_metadata.graphql",
"variables": {
"user":"{user_id}"
},
"operationName": "getUserMetadata"
}
}
}
]
}
The documentation is only a piece of the help you can get! Whether you are looking for Open Source or Enterprise support, see more support channels that can help you.
We use cookies to understand how you use our site and to improve your overall experience. By continuing to use our site, you accept our Privacy Policy. More information