Skip to content

Commit 048c1de

Browse files
authored
docs: add actions docs (hasura#3907)
1 parent bb63d7e commit 048c1de

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+2199
-103
lines changed
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
Action handlers
2+
===============
3+
4+
5+
.. contents:: Table of contents
6+
:backlinks: none
7+
:depth: 1
8+
:local:
9+
10+
Introduction
11+
------------
12+
13+
Actions need to be backed by custom business logic. This business logic can be
14+
defined in a handler which is an HTTP webhook.
15+
16+
17+
HTTP handler
18+
------------
19+
20+
When the action mutation is called, Hasura makes a ``POST`` request to the
21+
handler with the mutation arguments and the session variables.
22+
23+
The request payload is of the format:
24+
25+
.. code-block:: json
26+
27+
{
28+
"action": "<action-name>",
29+
"input": {
30+
"arg1": "<value>",
31+
"arg2": "<value>"
32+
},
33+
"session_variables": {
34+
"x-hasura-user-id": "<session user id>",
35+
"x-hasura-role": "<session user role>"
36+
}
37+
}
38+
39+
40+
Returning a success response
41+
----------------------------
42+
43+
To return a success response, you must send back a response payload of action's
44+
response type. The HTTP status code must be ``2xx`` for a successful response.
45+
46+
Returning an error response
47+
---------------------------
48+
49+
To return an error response, you must send back an error object or a list of
50+
error objects. An error object looks like:
51+
52+
.. code-block:: json
53+
54+
{
55+
"message": "<error message>"
56+
}
57+
58+
The HTTP status code must be ``4xx`` for an error response.
59+
60+
61+
Example
62+
-------
63+
64+
For example, consider the following mutation.
65+
66+
.. code-block:: graphql
67+
68+
extend type Mutation {
69+
UserLogin (username: String!, email: String!): UserInfo
70+
}
71+
72+
type UserInfo {
73+
accessToken: String!
74+
userId: Int!
75+
}
76+
77+
Let's say, the following mutation is executed:
78+
79+
.. code-block:: graphql
80+
81+
mutation {
82+
UserLogin (username: "jake", password: "secretpassword") {
83+
accessToken
84+
userId
85+
}
86+
}
87+
88+
89+
Hasura will call the handler with the following payload:
90+
91+
.. code-block:: json
92+
93+
{
94+
"action": "UserInfo",
95+
"input": {
96+
"username": "jake",
97+
"password": "secretpassword"
98+
},
99+
"session_variables": {
100+
"x-hasura-user-id": "423",
101+
"x-hasura-role": "user"
102+
}
103+
}
104+
105+
To return a success response, you must send the response of the action's output
106+
type (in this case, ``UserInfo``) with a status code ``2xx``. So a sample
107+
response would be:
108+
109+
.. code-block:: json
110+
111+
{
112+
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVC",
113+
"userId": 4829
114+
}
115+
116+
To throw an error, you must a response payload of the followin type while
117+
setting the status code as ``4xx``.
118+
119+
.. code-block:: json
120+
121+
{
122+
"message": "invalid credentials"
123+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
Async actions
2+
=============
3+
4+
.. contents:: Table of contents
5+
:backlinks: none
6+
:depth: 1
7+
:local:
8+
9+
Sometimes you may not want to wait for an action to complete before sending a
10+
response back to the client (say if the business logic takes a long time). In
11+
such cases you can create an **asynchronous** action, which returns an
12+
``action_id`` immediately to the client before contacting the handler.
13+
14+
If you mark an action as **asynchronous**, Hasura also generates a
15+
``query`` and a ``subscription`` field for the action so that you can
16+
query/subscribe to its status.
17+
18+
For example, let's say ``place_order`` is an asynchronous action
19+
20+
.. code-block:: graphql
21+
22+
mutation placeOrderRequest($order_input: place_order_input!) {
23+
place_order(input: $order_input)
24+
}
25+
26+
Executing this mutation will return a response like:
27+
28+
.. code-block:: json
29+
30+
{
31+
"data": {
32+
"place_order": "23b1c256-7aff-4b95-95bd-68220d9f93f2"
33+
}
34+
}
35+
36+
The returned ``uuid`` is the ``action id`` of the async action. To get the actual
37+
response of the action, you can ``query`` or ``subscribe`` to the action
38+
using this ``action id``.
39+
40+
.. code-block:: graphql
41+
42+
subscription getPlaceOrderResponse {
43+
place_order (id: "23b1c256-7aff-4b95-95bd-68220d9f93f2") {
44+
output
45+
errors
46+
}
47+
}
48+
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
Actions codegen
2+
===============
3+
4+
.. contents:: Table of contents
5+
:backlinks: none
6+
:depth: 1
7+
:local:
8+
9+
Introduction
10+
------------
11+
12+
Actions need HTTP handlers to run the business logic. It might be inconvenient
13+
to write the complete handler code for every action. Luckily, GraphQL's type
14+
system allows us to auto-generate the boilerplate code for actions.
15+
16+
17+
.. note::
18+
19+
Hasura currently has codegen set up for a few frameworks. The list of
20+
supported frameworks should grow with contributions from the
21+
community.
22+
23+
Generating handler code for your action
24+
---------------------------------------
25+
26+
.. rst-class:: api_tabs
27+
.. tabs::
28+
29+
.. tab:: Console
30+
31+
Head to the ``Actions -> [action-name] -> Codegen`` tab in the console
32+
33+
You can select the framework of your choice to get the corresponding
34+
handler boilerplate code.
35+
36+
.. thumbnail:: ../../../img/graphql/manual/actions/codegen/console-codegen-tab.png
37+
:alt: Console codegen tab
38+
39+
40+
.. tab:: CLI
41+
42+
**Configuration**
43+
44+
Before being able to codegen for actions, you have to configure your CLI.
45+
46+
Run:
47+
48+
.. code-block:: bash
49+
50+
hasura actions use-codegen
51+
52+
1. Choose which framework you want to codegen for:
53+
54+
.. thumbnail:: ../../../img/graphql/manual/actions/codegen/cli-framework-prompt.png
55+
:alt: CLI Framework Prompt
56+
57+
2. Choose if you also wish to clone a starter kit for the chosen framework:
58+
59+
.. thumbnail:: ../../../img/graphql/manual/actions/codegen/cli-starter-kit-prompt.png
60+
:alt: CLI Starter Kit Prompt
61+
62+
3. Choose a path where you want to output the auto-generated code files
63+
64+
.. thumbnail:: ../../../img/graphql/manual/actions/codegen/cli-output-dir-prompt.png
65+
:alt: CLI Starter Kit Prompt
66+
67+
68+
This command will update your ``config.yaml`` with the codegen config as per
69+
your preferences. You can also set these values manually in ``config.yaml``.
70+
71+
For example:
72+
73+
.. code-block:: yaml
74+
:emphasize-lines: 8-10
75+
76+
version: "2"
77+
endpoint: http://localhost:8080
78+
metadata_directory: metadata
79+
migrations_directory: migrations
80+
actions:
81+
handler_webhook_baseurl: http://localhost:3000
82+
kind: synchronous
83+
codegen:
84+
framework: nodejs-express
85+
output_dir: ./nodejs-express/src/handlers/
86+
87+
88+
89+
**Codegen**
90+
91+
92+
To finally get auto-generated code for an action, run:
93+
94+
.. code-block:: bash
95+
96+
hasura actions codegen <action-name>
97+
98+
The codegen files will be generated at the ``output_dir`` path from ``config.yaml``.
99+
100+
101+
Building a codegen for your framework
102+
-------------------------------------
103+
104+
As of now, Hasura provides codegen for a few frameworks (``nodejs-express``,
105+
``typescript-zeit``, etc).
106+
107+
If you wish to build a code generator for your framework
108+
`read the contrib guide <https://github.com/hasura/codegen-builder-contrib/>`_.
109+
110+
111+

0 commit comments

Comments
 (0)