REST Connectors for Actions
Introduction
REST Connectors for actions are used to integrate existing REST APIs to the GraphQL API without needing any middleware or modifications to the upstream code.
REST Connectors modify the default HTTP request made by an action to adapt to your webhook's expected format by adding suitable transforms.
General information about the templating used in REST Connectors can be found in the Kriti templating section of the documentation.
REST Connectors are supported in Hasura GraphQL Engine versions v2.1.0
and above
Configuring REST Connectors
REST Connectors can be configured either when creating a new action or editing an existing one. See the transform options here:
- Console
- CLI
- API
Go to the Actions
tab on the console and create or modify an action. Scroll down to Configure REST Connectors
section:
Update the actions.yaml
file inside the metadata
directory and add a [request_transform](RequestTransformation]
field to the action:
- name: create_user
definition:
kind: synchronous
handler: https://action.my_app.com/create-user
timeout: 60
request_transform:
template_engine: Kriti
method: POST
content_type: application/json
url: '{{$base_url}}/create_user'
query_params:
id: "{{$session_variables['x-hasura-user-id']}}"
body: '{"username": {{$body.input.username}}}'
comment: Custom action to create user
Apply the metadata by running:
hasura metadata apply
REST Connectors can be configured for actions using the create_action or update_action metadata APIs by adding a request_transform field to the args:
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type":"create_action",
"args":{
"name":"create_user",
"definition":{
"kind":"synchronous",
"arguments":[
{
"name":"username",
"type":"String!"
},
{
"name":"email",
"type":"String!"
}
],
"output_type":"User",
"handler":"https://action.my_app.com/create-user",
"timeout":60,
"request_transform": {
"template_engine": "Kriti",
"method": "POST",
"url": "{{$base_url}}/create_user",
"query_params": {
"id": "{{$session_variables['x-hasura-user-id']}}"
},
"content_type": "application/json",
"body": "{\"username\": {{$body.input.username}}}"
}
},
"comment": "Custom action to create user"
}
}
Context Variables
You can use context variables in the transforms to achieve dynamic behavior for each request.
The context variables available in transforms are:
Context variable | Value |
---|---|
$body | Original body of action request |
$base_url | Original configured webhook handler URL |
$session_variables | Session variables |
In addition to these variables, the following functions are available in addition to the standard Basic Functions:
Context variable | Value |
---|---|
getSessionVariable(NAME) | Look up a session variable by name (case-insensitive) |
Console sample context
The console allows you to preview your transforms while configuring them. To avoid exposing sensitive information on the console UI the actual environment variables configured on the server are not resolved while displaying the previews. Also any session variables used in the transform will not be available at the time of configuration.
Hence, the console allows you to provide mock env variables and session variables to verify your transforms. If you configure your transforms without providing the mock env/session variables you might see a UI validation error in the preview sections.
For example: If your webhook handler is set as an env var as shown below then pass a mock value for that env var in the sample context:
You can enter the mock env/session variables under Configure REST Connectors > Sample Context
:
As the sample context is only used for previews, you can still configure the transforms on the console without setting any sample context.
Types of transforms
REST Connectors allow you to add different transforms to the default HTTP request. You can also use context variables in the transforms to achieve dynamic behavior for each request.
You can transform your:
Request Method
You can change the request method to adapt to your API's expected format.
- Console
- CLI
- API
In the Configure REST Connectors
section, click on Add Request Options Transform
:
Update the actions.yaml
file inside the metadata
directory and add a request_transform
field to the action:
- name: create_user
definition:
kind: synchronous
handler: https://action.my_app.com/create-user
timeout: 60
request_transform:
template_engine: Kriti
method: POST
content_type: application/json
url: '{{$base_url}}/create_user'
query_params:
id: '{{$session_variables[''x-hasura-user-id'']}}'
body: '{"username": {{$body.input.username}}}'
comment: Custom action to create user
Apply the metadata by running:
hasura metadata apply
REST Connectors can be configured for actions using the create_action or update_action metadata APIs by adding a request_transform field to the args:
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type":"create_action",
"args":{
"name":"create_user",
"definition":{
"kind":"synchronous",
"arguments":[
{
"name":"username",
"type":"String!"
},
{
"name":"email",
"type":"String!"
}
],
"output_type":"User",
"handler":"{{ACTION_BASE_URL}}",
"timeout":60,
"request_transform": {
"template_engine": "Kriti",
"method": "POST",
"url": "{{$base_url}}/create_user",
"query_params": {
"id": "{{$session_variables['x-hasura-user-id']}}"
},
"content_type": "application/json",
"body": "{\"username\": {{$body.input.username}}}"
}
},
"comment": "Custom action to create user"
}
}
Request URL
The Request URL template allows you to configure the exact API endpoint to call.
You can use the context variables to construct the final URL.
You can also provide query params to add to the URL.
You can use the Kriti templating language to construct any string values here.
- Console
- CLI
- API
In the Configure REST Connectors
section, click on Add Request Options Transform
:
The value of the final url should be reflected in the Preview
section given all required
sample context is set.
Hit Save Action
to apply your changes.
Update the actions.yaml
file inside the metadata
directory and add a request_transform
field to the action:
- name: create_user
definition:
kind: synchronous
handler: https://action.my_app.com/create-user
timeout: 60
request_transform:
template_engine: Kriti
method: POST
content_type: application/json
url: '{{$base_url}}/create_user'
query_params:
id: '{{$session_variables[''x-hasura-user-id'']}}'
body: '{"username": {{$body.input.username}}}'
comment: Custom action to create user
Apply the metadata by running:
hasura metadata apply
REST Connectors can be configured for actions using the create_action or update_action metadata APIs by adding a request_transform field to the args:
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type":"create_action",
"args":{
"name":"create_user",
"definition":{
"kind":"synchronous",
"arguments":[
{
"name":"username",
"type":"String!"
},
{
"name":"email",
"type":"String!"
}
],
"output_type":"User",
"handler":"{{ACTION_BASE_URL}}",
"timeout":60,
"request_transform": {
"template_engine": "Kriti",
"method": "POST",
"url": "{{$base_url}}/create_user",
"query_params": {
"id": "{{$session_variables['x-hasura-user-id']}}"
},
"content_type": "application/json",
"body": "{\"username\": {{$body.input.username}}}"
}
},
"comment": "Custom action to create user"
}
}
Note that you must use the escapeUri
function to urlencode templated values. For example, if you have to use session
variables in the URL and those may contain non-ASCII values, then you should provide the template URL as
{{$base_url}}/{{escapeUri $session_variables['x-hasura-user-id']}}
Query params with key/value pairs which evaluate to null
are ignored by Hasura while performing the HTTP API call.
Hasura considers such query params optional.
For example, consider a query param value with template {{$session_variables?['x-hasura-user-id']}}
. If the variable
x-hasura-user-id
is absent in the session variables, then the query param will be omitted from the HTTP API call.
Request Body
You can generate a custom request body by configuring a template to transform the default payload to a custom payload.
Request body could be provided using the body
field as an object,
which additionally gives the ability to disable request body, transform request body to application/json
, or transform
request body to x_www_form_urlencoded
formats.
- Disabling Request Body
- Request Body with application/json format
- Request Body with x_www_form_urlencoded format
Disabling Request Body
If you are using a GET
request, you might want to not send any request body, and additionally not send a
content-type
header to the webhook. You can do that using the disable body feature.
- Console
- CLI
- API
In the Configure REST Connectors
section, click on Add Request Options Transform
, and convert the Request Method
as GET
.
Then click on Add Payload Transform
, disable the payload body by using the dropdown next to the
Configure Request Body
section.
Hit Save Action
to apply your changes.
Update the actions.yaml
file inside the metadata
directory and add a request_transform
field to the action:
- name: create_user
definition:
kind: synchronous
handler: https://action.my_app.com/create-user
timeout: 60
request_transform:
template_engine: Kriti
version: 2
method: GET
url: '{{$base_url}}/create_user'
query_params:
id: '{{$session_variables[''x-hasura-user-id'']}}'
body:
action: 'remove'
request_headers:
remove_headers: ['content-type]
comment: Custom action to create user
Apply the metadata by running:
hasura metadata apply
REST Connectors can be configured for actions using the create_action or update_action metadata APIs by adding a request_transform field to the args:
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type":"create_action",
"args":{
"name":"create_user",
"definition":{
"kind":"synchronous",
"arguments":[
{
"name":"username",
"type":"String!"
},
{
"name":"email",
"type":"String!"
}
],
"output_type":"User",
"handler":"{{ACTION_BASE_URL}}",
"timeout":60,
"request_transform": {
"template_engine": "Kriti",
"version": 2,
"method": "GET",
"url": "{{$base_url}}/create_user",
"query_params": {
"id": "{{$session_variables['x-hasura-user-id']}}"
},
"body": {
"action": "remove"
},
"request_headers": {
"remove_headers": ["content-type"],
},
}
},
"comment": "Custom action to create user"
}
}
Request Body with application/json format
You can transform Request Body to application/json
format using the following steps:
- Console
- CLI
- API
In the Configure REST Connectors
section, click on Add Payload Transform
. By default console sends the body as
application/json
which can be seen in the dropdown next to the Configure Request Body
section.
Hit Save Action
to apply your changes.
Update the actions.yaml
file inside the metadata
directory and add a request_transform
field to the action:
- name: create_user
definition:
kind: synchronous
handler: https://action.my_app.com/create-user
timeout: 60
request_transform:
template_engine: Kriti
version: 2
method: POST
url: '{{$base_url}}/create_user'
query_params:
id: '{{$session_variables[''x-hasura-user-id'']}}'
body:
action: 'transform'
template: '{"username": {{$body.input.username}}}'
comment: Custom action to create user
Apply the metadata by running:
hasura metadata apply
REST Connectors can be configured for actions using the create_action or update_action metadata APIs by adding a request_transform field to the args:
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type":"create_action",
"args":{
"name":"create_user",
"definition":{
"kind":"synchronous",
"arguments":[
{
"name":"username",
"type":"String!"
},
{
"name":"email",
"type":"String!"
}
],
"output_type":"User",
"handler":"{{ACTION_BASE_URL}}",
"timeout":60,
"request_transform": {
"template_engine": "Kriti",
"version": 2,
"method": "POST",
"url": "{{$base_url}}/create_user",
"query_params": {
"id": "{{$session_variables['x-hasura-user-id']}}"
},
"body": {
"action": "transform"
"template": "{\"username\": {{$body.input.username}}}"
},
}
},
"comment": "Custom action to create user"
}
}
Request Body with x_www_form_urlencoded format
While doing x_www_form_urlencoded
transformation, please note that as all changes to the request must be made explicit
when calling the API, so you will need to remove the default application/json
header and add a
application/x-www-form-urlencoded
header.
- Console
- CLI
- API
In the Configure REST Connectors
section, click on Add Payload Transform
. Change the dropdown next to
Configure Request Body
section to x_www_form_urlencoded
. You can see the body transformed body in the
Transformed Request Body
section.
Hit Save Action
to apply your changes.
Update the actions.yaml
file inside the metadata
directory and add a request_transform
field to the action:
- name: create_user
definition:
kind: synchronous
handler: https://action.my_app.com/create-user
timeout: 60
request_transform:
template_engine: Kriti
version: 2
method: POST
url: '{{$base_url}}/create_user'
query_params:
id: '{{$session_variables[''x-hasura-user-id'']}}'
body:
action: 'x_www_form_urlencoded'
form_template:
username: '{{$body.input.username}}'
request_headers:
remove_headers: ['content-type']
add_headers:
'content-type': 'application/x-www-form-urlencoded'
comment: Custom action to create user
Apply the metadata by running:
hasura metadata apply
REST Connectors can be configured for actions using the create_action or update_action metadata APIs by adding a request_transform field to the args:
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type":"create_action",
"args":{
"name":"create_user",
"definition":{
"kind":"synchronous",
"arguments":[
{
"name":"username",
"type":"String!"
},
{
"name":"email",
"type":"String!"
}
],
"output_type":"User",
"handler":"{{ACTION_BASE_URL}}",
"timeout":60,
"request_transform": {
"template_engine": "Kriti",
"version": 2,
"method": "POST",
"url": "{{$base_url}}/create_user",
"query_params": {
"id": "{{$session_variables['x-hasura-user-id']}}"
},
"body": {
"action": "x_www_form_urlencoded",
"form_template": {
"username": "{{$body.input.username}}"
},
},
"request_headers": {
"remove_headers": ["content-type"],
"add_headers": {
"content-type": "application/x-www-form-urlencoded"
},
},
}
},
"comment": "Custom action to create user"
}
}
Response Body
You can transform the default body of your HTTP API response by configuring a response transform template. This can be used to match the output types defined in your Action with your HTTP API.
Response transforms are applicable only for JSON responses.
- Console
- CLI
- API
In the Configure REST Connectors
section, click on Add Response Transform
:
Hit Create Action
to apply your changes.
Update the actions.yaml
file inside the metadata
directory and add a response_transform
field to the Action:
- name: create_user
definition:
kind: synchronous
handler: https://action.my_app.com/create-user
timeout: 60
response_transform:
template_engine: Kriti
version: 2
body: '{"action": "transform", "template": "{\n \"test\":{{$body.input.arg1.id}}\n}"}'
Apply the metadata by running:
hasura metadata apply
REST Connectors can be configured for Actions using the create_action or update_action metadata APIs by adding a response_transform field to the args:
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type":"create_action",
"args":{
"name":"create_user",
"definition":{
"kind":"synchronous",
"arguments":[
{
"name":"username",
"type":"String!"
},
{
"name":"email",
"type":"String!"
}
],
"output_type":"User",
"handler":"{{ACTION_BASE_URL}}",
"timeout":60,
"response_transform": {
"template_engine": "Kriti",
"version": 2,
"body": {"action": "transform", "template": "{\n \"test\":{{$body.input.arg1.id}}\n}"},
"comment": "Custom action to create user"
}
}
}
}
Example
Let's integrate Auth0's management API to update the profile of a user:
- Console
- CLI
- API
Go to the Actions
tab on the console and create or modify an action. Scroll down to Configure REST Connectors
section:
Action definition:
The transformation is given by:
To be added
Action definition:
type Mutation {
updateProfile(picture_url: String!): ProfileOutput
}
type ProfileOutput {
id: String!
user_metadata: String!
}
The transform is given by:
{
"request_transform": {
"body": "{\"user_metadata\": {\"picture\": {{$body.input.picture_url}} } }",
"url": "{{$base_url}}/{{$session_variables['x-hasura-user-id']}}",
"method": "PATCH"
}
}