docs: REST connectors for Event Triggers

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/3606
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Rikin Kachhia <54616969+rikinsk@users.noreply.github.com>
GitOrigin-RevId: e95567a316e088245d55044194260784136e3b6d
This commit is contained in:
Divya Bhushan 2022-03-24 18:03:23 +05:30 committed by hasura-bot
parent 6ad050a29c
commit d4d5e3d50a
27 changed files with 1161 additions and 138 deletions

View File

@ -15,11 +15,10 @@ REST Connectors for actions
Introduction
------------
REST Connectors for actions are used to integrate existing REST APIs as GraphQL APIs
without changing any upstream code.
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 work by changing the default HTTP request made by an action to a
different HTTP request by adding suitable transforms.
REST Connectors modify the default HTTP request made by an action to adapt to your webhook's expected format by adding suitable transforms.
.. admonition:: Supported from
@ -28,6 +27,8 @@ different HTTP request by adding suitable transforms.
Configuring REST Connectors
---------------------------
REST Connectors can be configured either when creating a new action or editing an existing one. See the transform options :ref:`here <action_transform_types>`:
.. rst-class:: api_tabs
.. tabs::
@ -40,17 +41,42 @@ Configuring REST Connectors
.. tab:: CLI
Will be added soon
Update the ``actions.yaml`` file inside the ``metadata`` directory and add
a :ref:`request_transform <RequestTransformation>` field to the action:
.. code-block:: yaml
:emphasize-lines: 6-13
- 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:
.. code-block:: bash
hasura metadata apply
.. tab:: API
REST Connectors can be added to actions using the :ref:`create_action metadata API <metadata_create_action>` or
:ref:`update_action metadata API <metadata_update_action>` by adding a
REST Connectors can be configured for actions using the :ref:`metadata_create_action` or
:ref:`metadata_update_action` metadata APIs by adding a
:ref:`request_transform <RequestTransformation>` field to the args:
.. code-block:: http
:emphasize-lines: 24-26
:emphasize-lines: 24-33
POST /v1/metadata HTTP/1.1
Content-Type: application/json
@ -76,21 +102,26 @@ Configuring REST Connectors
"handler":"https://action.my_app.com/create-user",
"timeout":60,
"request_transform": {
"body": "{{$body.input.name}}"
},
"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"
}
}
Types of transforms
-------------------
REST Connectors allows you to add different types of "transforms" to the default HTTP request.
You can also use "context variables" in the transforms to achieve dynamic behaviour for each request.
.. _action_transform_context_variables:
Context Variables
*****************
^^^^^^^^^^^^^^^^^
You can use context variables in the transforms to achieve dynamic behavior for each request.
The context variables available in transforms are:
@ -104,81 +135,257 @@ The context variables available in transforms are:
- Original body of action request
* - $base_url
- Original configured URL
- Original configured webhook handler URL
* - $session_variables
- Session variables
Sample Context
~~~~~~~~~~~~~~
.. _action_transforms_sample_context:
The console allows you to provide mock ``session variables`` and ``env variables`` to test your transforms.
Console sample context
**********************
Configure an ``env var`` in the action webhook handler.
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.
.. thumbnail:: /img/graphql/core/actions/transformation-context-vars-0.png
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:
.. thumbnail:: /img/graphql/core/actions/transform-sample-context-0.png
:alt: Console action webhook handler
:width: 800px
:width: 650px
Add the ``env var`` value to the ``Sample Context`` under ``Sample Env Variables``.
You can enter the mock env/session variables under ``Configure REST Connectors > Sample Context``:
.. thumbnail:: /img/graphql/core/actions/transformation-context-vars-1.png
:alt: Console action context env
:width: 800px
.. thumbnail:: /img/graphql/core/actions/transform-sample-context-1.png
:alt: Add generic sample context
:width: 800px
The value should be reflected in the ``{{$base_url}}`` in ``Change Request Options`` section:
.. note::
.. thumbnail:: /img/graphql/core/actions/transformation-context-vars-2.png
:alt: Console action req options transformation
:width: 800px
As the sample context is only used for previews, you can still configure the transforms on the console without setting any sample context.
``Session vars`` can also be added to the ``Sample context`` as shown above,
and used like so: ``{{$session_variables['x-hasura-user-id']}}``.
The above screen also shows an example of using the session vars from context.
.. _action_transform_types:
.. admonition:: Context variables validation error
Types of transforms
-------------------
Actual environment variables are not resolved during testing transforms as it could expose sensitive information to the UI.
Note that if you don't provide mock ``env/session variables`` and test your transform, you would get a UI validation error.
Considering this section is only used for testing, ``Create Action`` button will still be usable.
When you click on ``Create Action``, any referenced envs are validated at the server without leaking any sensitive information to the UI.
REST Connectors allow you to add different transforms to the default HTTP request. You can also use :ref:`context variables <action_transform_context_variables>`
in the transforms to achieve dynamic behavior for each request.
You can transform your:
.. contents::
:backlinks: none
:depth: 1
:local:
Request body
************
Request Method
^^^^^^^^^^^^^^
Generate a request body by configuring a template to transform the default payload to a custom payload.
The ``body`` field takes a template in the `Kriti templating language <https://github.com/hasura/kriti-lang>`__ to evaluate the transform.
You can change the request method to adapt to your API's expected format.
.. rst-class:: api_tabs
.. tabs::
.. tab:: Console
In the ``Configure REST Connectors`` section, click on ``Add Payload Transform``:
In the ``Configure REST Connectors`` section, click on ``Add Request Options Transform``:
.. thumbnail:: /img/graphql/core/actions/payload-transform.png
:alt: Add payload transformation
:width: 1100px
.. thumbnail:: /img/graphql/core/actions/transform-method.png
:alt: Change request method
:width: 800px
.. tab:: CLI
Will be added soon
Update the ``actions.yaml`` file inside the ``metadata`` directory and add
a :ref:`request_transform <RequestTransformation>` field to the action:
.. code-block:: yaml
:emphasize-lines: 8
- 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:
.. code-block:: bash
hasura metadata apply
.. tab:: API
.. code-block:: json
:emphasize-lines: 3
REST Connectors can be configured for actions using the :ref:`metadata_create_action` or
:ref:`metadata_update_action` metadata APIs by adding a
:ref:`request_transform <RequestTransformation>` field to the args:
{
"request_transform": {
"body": "{\n \"users\": {\n \"name\": {{$body.input.arg1.username}},\n \"password\": {{$body.input.arg1.password}}\n }\n}",
}
}
Content Type
************
.. code-block:: http
:emphasize-lines: 26
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 :ref:`context variables <action_transform_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 <https://github.com/hasura/kriti-lang>`__ to construct any string values here.
.. rst-class:: api_tabs
.. tabs::
.. tab:: Console
In the ``Configure REST Connectors`` section, click on ``Add Request Options Transform``:
.. thumbnail:: /img/graphql/core/actions/transform-url.png
:alt: Change request URL
:width: 800px
The value of the final url should be reflected in the ``Preview`` section given all required :ref:`sample context <action_transforms_sample_context>` is set.
Hit ``Save Action`` to apply your changes.
.. tab:: CLI
Update the ``actions.yaml`` file inside the ``metadata`` directory and add
a :ref:`request_transform <RequestTransformation>` field to the action:
.. code-block:: yaml
:emphasize-lines: 10-12
- 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:
.. code-block:: bash
hasura metadata apply
.. tab:: API
REST Connectors can be configured for actions using the :ref:`metadata_create_action` or
:ref:`metadata_update_action` metadata APIs by adding a
:ref:`request_transform <RequestTransformation>` field to the args:
.. code-block:: http
:emphasize-lines: 27-30
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"
}
}
.. admonition:: escapeUri
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']}}``
Request Content-Type
^^^^^^^^^^^^^^^^^^^^
You can change the ``Content-Type`` of the request to either ``application/json`` or ``x-www-form-urlencoded``. The default is ``application/json``.
@ -191,97 +398,182 @@ You can change the ``Content-Type`` of the request to either ``application/json`
.. tab:: CLI
Will be added soon
Update the ``actions.yaml`` file inside the ``metadata`` directory and add
a :ref:`request_transform <RequestTransformation>` field to the action:
.. code-block:: yaml
:emphasize-lines: 9
- 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:
.. code-block:: bash
hasura metadata apply
.. tab:: API
.. code-block:: json
:emphasize-lines: 7
REST Connectors can be configured for actions using the :ref:`metadata_create_action` or
:ref:`metadata_update_action` metadata APIs by adding a
:ref:`request_transform <RequestTransformation>` field to the args:
{
"request_transform": {
"body": {
"name": "{{$body.input.name}}",
"email": "{{$body.input.email}}",
.. code-block:: http
:emphasize-lines: 31
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}}}"
}
},
"content_type": "x-www-form-urlencoded"
}
}
"comment": "Custom action to create user"
}
}
With ``x-www-form-urlencoded``, the key-value pairs in ``body`` are transformed to ``name={{$body.input.name}}&key2={{$body.input.email}}``.
URL
***
Request Body
^^^^^^^^^^^^
Transform the request URL. This can be used to embed, say user-id, in the url path.
You can also provide ``query_params`` to add to the URL.
You can use the `Kriti templating language <https://github.com/hasura/kriti-lang>`__ to construct any string value here.
.. rst-class:: api_tabs
.. tabs::
.. tab:: Console
In the ``Configure REST Connectors`` section, click on ``Add Request Options Transform``:
.. thumbnail:: /img/graphql/core/actions/request-options-transform.png
:alt: Change request URL
:width: 800px
.. tab:: CLI
Will be added soon
.. tab:: API
.. code-block:: json
:emphasize-lines: 3
{
"request_transform": {
"url": "{{$base_url}}/{{$session_variables['x-hasura-user-id']}}",
"query_params": {
"param1": "{{$body.input.value1}}",
"param2": "{{$body.input.value2}}"
}
}
}
.. admonition:: escapeUri
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']}}``
Method
******
Transform the method. This can be used to change the request method, say from ``POST`` to ``GET``, as shown below.
You can generate a custom request body by configuring a template to transform the default payload to a custom payload.
The ``body`` field takes a template in the `Kriti templating language <https://github.com/hasura/kriti-lang>`__ to evaluate the transform.
.. rst-class:: api_tabs
.. tabs::
.. tab:: Console
In the ``Configure REST Connectors`` section, click on ``Add Request Options Transform``:
In the ``Configure REST Connectors`` section, click on ``Add Payload Transform``:
.. thumbnail:: /img/graphql/core/actions/request-method-transform.png
:alt: Change request method
:width: 800px
A sample payload input auto-generated based on your schema is shown.
.. thumbnail:: /img/graphql/core/actions/transform-body.png
:alt: Add payload transformation
:width: 1100px
The transformed sample payload should be shown as the ``Transformed Request Body`` given all required :ref:`sample context <action_transforms_sample_context>` is set.
Hit ``Save Action`` to apply your changes.
.. tab:: CLI
Will be added soon
Update the ``actions.yaml`` file inside the ``metadata`` directory and add
a :ref:`request_transform <RequestTransformation>` field to the action:
.. code-block:: yaml
:emphasize-lines: 13
- 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:
.. code-block:: bash
hasura metadata apply
.. tab:: API
.. code-block:: json
:emphasize-lines: 3
REST Connectors can be configured for actions using the :ref:`metadata_create_action` or
:ref:`metadata_update_action` metadata APIs by adding a
:ref:`request_transform <RequestTransformation>` field to the args:
.. code-block:: http
:emphasize-lines: 32
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_transform": {
"method": "GET"
}
}
Example
-------
@ -314,7 +606,7 @@ Let's integrate Auth0's management API to update the profile of a user:
.. tab:: CLI
Will be added soon
To be added
.. tab:: API

View File

@ -198,10 +198,13 @@ Following is the behaviour in detail:
3. third, check if ``Expires`` header is present (if ``Cache-Control`` is not present), and try
to parse the value as a timestamp.
2. If it is able to parse ``max-age``, ``s-maxage`` or ``Expires`` successfully, then it will use that parsed time to refresh/refetch the JWKs again.
If it is unable to parse, then it will not refresh the JWKs (it assumes that if the above headers are not present, the provider doesn't rotate their JWKs). If the parsed time is less than a second, the JWKs will be fetched once per second regardless.
If ``must-revalidate`` and ``max-age`` are present, then it will refresh the JWK again after the time period specified in ``max-age`` has passed.
However, if ``max-age`` is not specified or if ``no-cache`` or ``no-store`` are present, then it will refresh the JWKs once a second.
2. If it is able to parse ``max-age``, ``s-maxage`` or ``Expires`` successfully, then it will use that parsed time to refresh/refetch the JWKs again.
If it is unable to parse, then it will not refresh the JWKs (it assumes that if the above headers are not present, the provider doesn't rotate their JWKs). If the parsed time is less than a second, the JWKs will be fetched once per second regardless.
If ``must-revalidate`` and ``max-age`` are present, then it will refresh the JWK again after the time period specified in ``max-age`` has passed.
However, if ``max-age`` is not specified or if ``no-cache`` or ``no-store`` are present, then it will refresh the JWKs once a second.
**While running**:

View File

@ -30,7 +30,7 @@ Event triggers can be created using the Hasura console, CLI or metadata APIs.
.. tab:: CLI
You can add an event triggers in the ``tables.yaml`` file inside the ``metadata`` directory:
You can add an event trigger for a table by updating the ``databases > [source-name] > tables > [table-name].yaml`` file inside the ``metadata`` directory:
.. code-block:: yaml
:emphasize-lines: 4-12

View File

@ -15,8 +15,7 @@ Event Triggers
Introduction
------------
Hasura can be used to create event triggers on tables in the Postgres database. Event triggers reliably capture
events on specified tables and invoke webhooks to carry out any custom logic.
Hasura can be used to create event triggers on tables in the Postgres database. Event triggers reliably capture events on specified tables and invoke webhooks to carry out any custom logic.
.. thumbnail:: /img/graphql/core/event-triggers/data-triggers-arch.png
:class: no-shadow
@ -32,8 +31,7 @@ Events can be of the following types:
.. note::
Event webhook notifications will be delivered at least once, and may arrive out of order with
respect to the underlying event.
Event webhook notifications will be delivered at least once, and may arrive out of order with respect to the underlying event.
Learn more
----------
@ -44,7 +42,8 @@ Learn more
create-trigger
payload
rest-connectors
Invoke trigger manually <invoke-trigger-manually>
serverless
samples
Invoke trigger manually <invoke-trigger-manually>
clean-up

View File

@ -18,7 +18,7 @@ Invoke event trigger manually
.. tab:: Console
You can select the ``Via console`` trigger operation while :ref:`creating an event trigger <create_trigger>`
to allow invoking the event trigger on rows manually using the Hasura console *(available after version v1.0.0-beta.1)*.
to allow invoking the event trigger on rows manually using the Hasura console.
In the ``Data -> [table-name] -> Browse Rows`` tab, clicking the ``invoke trigger`` button next to any row lets
you invoke "manual event triggers" configured on the table with that row as payload *(the button will be shown

View File

@ -0,0 +1,729 @@
.. meta::
:description: Rest Connectors for event triggers
:keywords: hasura, docs, event trigger, transforms, rest connectors
.. _events_rest_connectors:
REST Connectors for event triggers
==================================
.. contents:: Table of contents
:backlinks: none
:depth: 2
:local:
Introduction
------------
REST Connectors for event triggers are used to invoke existing or third-party webhooks without needing any middleware or modifications to the upstream code.
REST Connectors modify the event trigger's HTTP request to adapt to your webhook's expected format by adding suitable transforms.
.. admonition:: Supported from
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 event trigger or editing an existing one. See the transform options :ref:`here <event_trigger_transform_types>`:
.. rst-class:: api_tabs
.. tabs::
.. tab:: Console
Go to the ``Events`` tab on the console and create or modify an event trigger. Scroll down to ``Configure REST Connectors`` section:
.. thumbnail:: /img/graphql/core/event-triggers/transform-configure-rest-connectors.png
:alt: Configure REST Connectors for event triggers
.. tab:: CLI
Update the ``databases > [source-name] > tables > [table-name].yaml`` file inside the ``metadata`` directory and add
a :ref:`request_transform <RequestTransformation>` field to the event trigger:
.. code-block:: yaml
:emphasize-lines: 13-
table:
name: users
schema: public
event_triggers:
- name: insert_trigger_on_users
definition:
insert:
columns: "*"
webhook: https://api.somedomain.com
headers:
- name: Authorization
value: bearer-xxxx
request_transform:
template_engine: Kriti
method: POST
url: "{{$base_url}}/api/v3/endpoint"
query_params:
query_param: xxxxx
content_type: application/json
body: "{\n \"table\": {\n \"name\": {{$body.table.name}},\n \"schema\": {{$body.table.schema}}\n },\n \"To\": {\n \"username\": {{$body.event.data.new.name}},\n \"email\": {{$body.event.data.new.email}}\n }\n}"
Apply the metadata by running:
.. code-block:: bash
hasura metadata apply
.. tab:: API
You can configure REST Connectors for event triggers using the :ref:`metadata_pg_create_event_trigger` metadata API and adding a
:ref:`request_transform <RequestTransformation>` field to the args:
.. code-block:: http
:emphasize-lines: 25-34
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type": "pg_create_event_trigger",
"args": {
"name": "insert_trigger_on_users",
"replace": true,
"source": "default",
"table": {
"name": "users",
"schema": "public"
},
"webhook": "https://api.somedomain.com",
"insert": {
"columns": "*"
},
"headers": [
{
"name": "Authorization",
"value": "bearer xxxx"
}
],
"request_transform": {
"template_engine": "Kriti",
"method": "POST",
"url": "{{$base_url}}/api/v3/endpoint",
"query_params": {
"query_param": "xxxxx"
},
"content_type": "application/json",
"body": "{\n \"table\": {\n \"name\": {{$body.table.name}},\n \"schema\": {{$body.table.schema}}\n },\n \"To\": {\n \"username\": {{$body.event.data.new.name}},\n \"email\": {{$body.event.data.new.email}}\n }\n}"
}
}
}
.. _event_trigger_transform_context_variables:
Context Variables
^^^^^^^^^^^^^^^^^
You can use context variables in the transforms to achieve dynamic behavior for each request.
The context variables available in transforms are:
.. list-table::
:header-rows: 1
* - Context variable
- Value
* - $body
- Original body of event request
* - $base_url
- Original configured webhook URL
* - $session_variables
- Session variables
* - $query_params
- Query parameters and the values to be sent to the webhook
.. _event_trigger_transforms_sample_context:
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:
.. thumbnail:: /img/graphql/core/event-triggers/transform-sample-context-0.png
:alt: Console event trigger webhook handler
:width: 650px
You can enter the mock env/session variables under ``Configure REST Connectors > Sample Context``:
.. thumbnail:: /img/graphql/core/event-triggers/transform-sample-context-1.png
:alt: Add generic sample context
:width: 750px
.. note::
As the sample context is only used for previews, you can still configure the transforms on the console without setting any sample context.
.. _event_trigger_transform_types:
Types of transforms
-------------------
REST Connectors allow you to add different transforms to the default HTTP request. You can also use :ref:`context variables <event_trigger_transform_context_variables>`
in the transforms to achieve dynamic behavior for each request.
You can transform your:
.. contents::
:backlinks: none
:depth: 1
:local:
Request Method
^^^^^^^^^^^^^^
You can change the request method to adapt to your API's expected format.
.. rst-class:: api_tabs
.. tabs::
.. tab:: Console
Head to the ``Events > [event_trigger_name]`` page. Under ``Configure REST Connectors`` click on ``Add Request Options Transform``.
Select the ``Request Method``.
.. thumbnail:: /img/graphql/core/event-triggers/transform-request-method.png
:alt: Change request method
:width: 550px
Hit ``Save Event Trigger`` to apply your changes.
.. tab:: CLI
Update the ``databases > [source-name] > tables > [table-name].yaml`` file inside the ``metadata`` directory and add
a :ref:`request_transform <RequestTransformation>` field to the event trigger:
.. code-block:: yaml
:emphasize-lines: 15
table:
name: users
schema: public
event_triggers:
- name: insert_trigger_on_users
definition:
insert:
columns: "*"
webhook: https://api.somedomain.com
headers:
- name: Authorization
value: bearer-xxxx
request_transform:
template_engine: Kriti
method: POST
url: "{{$base_url}}/api/v3/endpoint"
query_params:
query_param: xxxxx
content_type: application/json
body: "{\n \"table\": {\n \"name\": {{$body.table.name}},\n \"schema\": {{$body.table.schema}}\n },\n \"To\": {\n \"username\": {{$body.event.data.new.name}},\n \"email\": {{$body.event.data.new.email}}\n }\n}"
Apply the metadata by running:
.. code-block:: bash
hasura metadata apply
.. tab:: API
You can configure REST Connectors for event triggers using the :ref:`metadata_pg_create_event_trigger` metadata API and adding a
:ref:`request_transform <RequestTransformation>` field to the args:
.. code-block:: http
:emphasize-lines: 27
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type": "pg_create_event_trigger",
"args": {
"name": "insert_trigger_on_users",
"replace": true,
"source": "default",
"table": {
"name": "users",
"schema": "public"
},
"webhook": "https://api.somedomain.com",
"insert": {
"columns": "*"
},
"headers": [
{
"name": "Authorization",
"value": "bearer xxxx"
}
],
"request_transform": {
"template_engine": "Kriti",
"method": "POST",
"url": "{{$base_url}}/api/v3/endpoint",
"query_params": {
"query_param": "xxxxx"
},
"content_type": "application/json",
"body": "{\n \"table\": {\n \"name\": {{$body.table.name}},\n \"schema\": {{$body.table.schema}}\n },\n \"To\": {\n \"username\": {{$body.event.data.new.name}},\n \"email\": {{$body.event.data.new.email}}\n }\n}"
}
}
}
Request URL
^^^^^^^^^^^
The Request URL template allows you to configure the exact API endpoint to call.
You can use the :ref:`context variables <event_trigger_transform_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 <https://github.com/hasura/kriti-lang>`__ to construct any string values here.
.. rst-class:: api_tabs
.. tabs::
.. tab:: Console
Head to the ``Events > [event_trigger_name]`` page. Under ``Configure REST Connectors`` click on ``Add Request Options Transform``.
Enter the ``Request URL Template`` and ``Query Params``.
.. thumbnail:: /img/graphql/core/event-triggers/transform-request-options.png
:alt: Console event trigger request options transformation
:width: 750px
The value of the final url should be reflected in the ``Preview`` section given all required :ref:`sample context <event_trigger_transforms_sample_context>` is set.
Hit ``Save Event Trigger`` to apply your changes.
.. tab:: CLI
Update the ``databases > [source-name] > tables > [table-name].yaml`` file inside the ``metadata`` directory and add
a :ref:`request_transform <RequestTransformation>` field to the event trigger:
.. code-block:: yaml
:emphasize-lines: 16-18
table:
name: users
schema: public
event_triggers:
- name: insert_trigger_on_users
definition:
insert:
columns: "*"
webhook: https://api.somedomain.com
headers:
- name: Authorization
value: bearer-xxxx
request_transform:
template_engine: Kriti
method: POST
url: "{{$base_url}}/api/v3/endpoint"
query_params:
query_param: xxxxx
content_type: application/json
body: "{\n \"table\": {\n \"name\": {{$body.table.name}},\n \"schema\": {{$body.table.schema}}\n },\n \"To\": {\n \"username\": {{$body.event.data.new.name}},\n \"email\": {{$body.event.data.new.email}}\n }\n}"
Apply the metadata by running:
.. code-block:: bash
hasura metadata apply
.. tab:: API
You can configure REST Connectors for event triggers using the :ref:`metadata_pg_create_event_trigger` metadata API and adding a
:ref:`request_transform <RequestTransformation>` field to the args:
.. code-block:: http
:emphasize-lines: 28-31
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type": "pg_create_event_trigger",
"args": {
"name": "insert_trigger_on_users",
"replace": true,
"source": "default",
"table": {
"name": "users",
"schema": "public"
},
"webhook": "https://api.somedomain.com",
"insert": {
"columns": "*"
},
"headers": [
{
"name": "Authorization",
"value": "bearer xxxx"
}
],
"request_transform": {
"template_engine": "Kriti",
"method": "POST",
"url": "{{$base_url}}/api/v3/endpoint",
"query_params": {
"query_param": "xxxxx"
},
"content_type": "application/json",
"body": "{\n \"table\": {\n \"name\": {{$body.table.name}},\n \"schema\": {{$body.table.schema}}\n },\n \"To\": {\n \"username\": {{$body.event.data.new.name}},\n \"email\": {{$body.event.data.new.email}}\n }\n}"
}
}
}
.. admonition:: escapeUri
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']}}``.
Request Content-Type
^^^^^^^^^^^^^^^^^^^^
You can change the ``Content-Type`` of the request to either ``application/json`` or ``x-www-form-urlencoded``. The default is ``application/json``.
.. rst-class:: api_tabs
.. tabs::
.. tab:: Console
Console support coming soon.
.. tab:: CLI
Update the ``databases > [source-name] > tables > [table-name].yaml`` file inside the ``metadata`` directory and add
a :ref:`request_transform <RequestTransformation>` field to the event trigger:
.. code-block:: yaml
:emphasize-lines: 19
table:
name: users
schema: public
event_triggers:
- name: insert_trigger_on_users
definition:
insert:
columns: "*"
webhook: https://api.somedomain.com
headers:
- name: Authorization
value: bearer-xxxx
request_transform:
template_engine: Kriti
method: POST
url: "{{$base_url}}/api/v3/endpoint"
query_params:
query_param: xxxxx
content_type: application/json
body: "{\n \"table\": {\n \"name\": {{$body.table.name}},\n \"schema\": {{$body.table.schema}}\n },\n \"To\": {\n \"username\": {{$body.event.data.new.name}},\n \"email\": {{$body.event.data.new.email}}\n }\n}"
Apply the metadata by running:
.. code-block:: bash
hasura metadata apply
.. tab:: API
You can configure REST Connectors for event triggers using the :ref:`metadata_pg_create_event_trigger` metadata API and adding a
:ref:`request_transform <RequestTransformation>` field to the args:
.. code-block:: http
:emphasize-lines: 32
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type": "pg_create_event_trigger",
"args": {
"name": "insert_trigger_on_users",
"replace": true,
"source": "default",
"table": {
"name": "users",
"schema": "public"
},
"webhook": "https://api.somedomain.com",
"insert": {
"columns": "*"
},
"headers": [
{
"name": "Authorization",
"value": "bearer xxxx"
}
],
"request_transform": {
"template_engine": "Kriti",
"method": "POST",
"url": "{{$base_url}}/api/v3/endpoint",
"query_params": {
"query_param": "xxxxx"
},
"content_type": "application/json",
"body": "{\n \"table\": {\n \"name\": {{$body.table.name}},\n \"schema\": {{$body.table.schema}}\n },\n \"To\": {\n \"username\": {{$body.event.data.new.name}},\n \"email\": {{$body.event.data.new.email}}\n }\n}"
}
}
}
With ``x-www-form-urlencoded``, the key-value pairs in ``body`` are transformed to ``name={{$body.input.name}}&key2={{$body.input.email}}``.
Request Body
^^^^^^^^^^^^
You can generate a custom request body by configuring a template to transform the default payload to a custom payload.
The ``body`` field takes a template in the `Kriti templating language <https://github.com/hasura/kriti-lang>`__ to evaluate the transform.
For example, you can obtain the following transformed event trigger request body for a ``users`` table:
.. thumbnail:: /img/graphql/core/event-triggers/transform-request-body.png
:alt: Transformed Request Body
:width: 900px
.. rst-class:: api_tabs
.. tabs::
.. tab:: Console
Head to ``Events > [event_trigger_name] > Modify`` tab.
Under ``Configure REST Connectors`` click on ``Add Payload Transform``.
A sample payload input auto-generated based on your schema is shown.
Under ``Configure Request Body`` enter the required request body template:
.. thumbnail:: /img/graphql/core/event-triggers/transform-generic-request-body.png
:alt: Configure request body
:width: 1100px
The transformed sample payload should be shown as the ``Transformed Request Body`` given all required :ref:`sample context <event_trigger_transforms_sample_context>` is set.
Hit ``Save Event Trigger`` to apply your changes.
.. tab:: CLI
Update the ``databases > [source-name] > tables > [table-name].yaml`` file inside the ``metadata`` directory and add
a :ref:`request_transform <RequestTransformation>` field to the event trigger:
.. code-block:: yaml
:emphasize-lines: 20
table:
name: users
schema: public
event_triggers:
- name: insert_trigger_on_users
definition:
insert:
columns: "*"
webhook: https://api.somedomain.com
headers:
- name: Authorization
value: bearer-xxxx
request_transform:
template_engine: Kriti
method: POST
url: "{{$base_url}}/api/v3/endpoint"
query_params:
query_param: xxxxx
content_type: application/json
body: "{\n \"table\": {\n \"name\": {{$body.table.name}},\n \"schema\": {{$body.table.schema}}\n },\n \"To\": {\n \"username\": {{$body.event.data.new.name}},\n \"email\": {{$body.event.data.new.email}}\n }\n}"
Apply the metadata by running:
.. code-block:: bash
hasura metadata apply
.. tab:: API
You can configure REST Connectors for event triggers using the :ref:`metadata_pg_create_event_trigger` metadata API and adding a
:ref:`request_transform <RequestTransformation>` field to the args:
.. code-block:: http
:emphasize-lines: 33
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type": "pg_create_event_trigger",
"args": {
"name": "insert_trigger_on_users",
"replace": true,
"source": "default",
"table": {
"name": "users",
"schema": "public"
},
"webhook": "https://api.somedomain.com",
"insert": {
"columns": "*"
},
"headers": [
{
"name": "Authorization",
"value": "bearer xxxx"
}
],
"request_transform": {
"template_engine": "Kriti",
"method": "POST",
"url": "{{$base_url}}/api/v3/endpoint",
"query_params": {
"query_param": "xxxxx"
},
"content_type": "application/json",
"body": "{\n \"table\": {\n \"name\": {{$body.table.name}},\n \"schema\": {{$body.table.schema}}\n },\n \"To\": {\n \"username\": {{$body.event.data.new.name}},\n \"email\": {{$body.event.data.new.email}}\n }\n}"
}
}
}
Example: Trigger SendGrid's Mail Send API
-----------------------------------------
To see the REST Connectors for event triggers in action, let's set up an event trigger to send an email using the `SendGrid Mail Send API <https://docs.sendgrid.com/api-reference/mail-send/mail-send>`__.
Let's say you have a table ``users (id int, name text, email text)`` and you would like to send the user an email whenever a new user is inserted into the ``users`` table.
Step 1: Configure event trigger details
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Head to the ``Events`` tab on your console and create a new event trigger.
The SendGrid Mail Send API is available at ``POST https://api.sendgrid.com/v3/mail/send`` and expects an ``Authorization`` header to be passed with a SendGrid API key for access
(see `docs <https://docs.sendgrid.com/api-reference/how-to-use-the-sendgrid-v3-api/authentication>`__).
You can configure env vars, say ``SENDGRID_BASE_URL`` with the value ``https://api.sendgrid.com`` and ``SENDGRID_API_KEY`` with the value ``Bearer <sendgrid-api-key>`` on the server so that
they can be used for this event trigger and any other SendGrid requests we might want to use in the future.
You can now configure the event trigger as follows:
**Table:** ``users``
**Operations:** ``Insert``
**Webhook:** ``SENDGRID_BASE_URL``
**Headers:** ``Authorization: SENDGRID_API_KEY``
.. thumbnail:: /img/graphql/core/event-triggers/transform-sendgrid-def.png
:alt: Sengrid event trigger config
:width: 900px
Step 2: Configure REST connector
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Step 2.1: Add Sample Context
****************************
Set a mock value for the ``SENDGRID_BASE_URL`` env var to verify your URL transform that we will be configuring next as the actual value is not exposed to the console.
.. thumbnail:: /img/graphql/core/event-triggers/transform-sendgrid-context.png
:alt: Sengrid event trigger context
:width: 750px
Step 2.2: Add Request Transforms
********************************
Request Method and URL template
"""""""""""""""""""""""""""""""
The SendGrid API request uses the ``POST`` request method so you can choose that.
We need to add ``/v3/mail/send`` to the SendGrid base URL (``https://api.sendgrid.com``) that we configured in the env var. This can be
done by setting the URL template as ``{{$base_url}}/v3/mail/send``.
.. thumbnail:: /img/graphql/core/event-triggers/transform-sendgrid-request.png
:alt: Sengrid event trigger request options
Request Body
""""""""""""
Here is the request body template we would need for the SendGrid Mail Send API (see `docs <https://docs.sendgrid.com/api-reference/mail-send/mail-send#body>`__).
We replace the ``email`` and ``name`` values from the event trigger body:
.. code-block:: none
:emphasize-lines: 9-10
{
"personalizations":
[
{
"from": { "email": "<from_email>", "name": "<from_name>" },
"to":
[
{
"email": {{ $body.event.data.new.email }},
"name": {{ $body.event.data.new.name }}
}
]
}
],
"from": { "email": "<from_email>", "name": "<from_name>" },
"reply_to": { "email": "<replyto_email>", "name": "<from_name>" },
"subject": "Welcome!",
"content":
[
{
"type": "text/html",
"value": "<p>Mail from a Hasura event trigger!</p>"
}
]
}
.. thumbnail:: /img/graphql/core/event-triggers/transform-sendgrid-body.png
:alt: Sengrid event trigger payload
:width: 1100px
Hit ``Create Event Trigger`` to complete the event trigger set up.
Step 3: Test the event trigger
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Insert a new user to the ``users`` table to call the SendGrid API.
Navigate to ``Data > [database-name] > public > users`` and insert a new row.
The ``insert`` operation triggers the event trigger and sends the transformed request to the SendGrid API which should send an email to the inserted user.
You can view the **Processed Events** and **Invocation Logs** for the event trigger to check the SendGrid API response.
.. thumbnail:: /img/graphql/core/event-triggers/transform-sendgrid-processed-events.png
:alt: Event trigger logs
:width: 1200px
.. note::
Explore the Hasura Data Hub source code for `Event Connectors <https://hasura.io/data-hub/event-transforms/>`_ with different platform integrations.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB