Hasura Actions using Netlify Functions for Custom Logic
In this guide, we will show how to write your own Hasura actions using Netlify functions (with your own custom business logic or a third-party API integration). But first, definitions.
What are Hasura actions?
Hasura provides support for integrating our own business logic or third-party APIs (usually REST APIs) with the help of “Hasura Actions”. Learn more about Hasura Actions.
What are Netlify functions?
Netlify functions are AWS’s serverless lambda functions that allow you to define your business logic and functions as an API and expose them with an endpoint. Click here to learn more about netlify functions.
How to write your own Hasura Actions using Netlify functions?
This guide will go through the process in three parts, feel free to skip to the part that is more interesting for you.
- Part I: Create a Function in an app
- Part II: Define the functions with logic
- Part III: Add the function to Hasura using Actions
Note: Hasura Actions can also be used to add REST endpoints to Hasura’s GraphQL schema.
Part I: Create a Function in an app
To create a function in the app, install the netlify-cli package from npm (preferably as global).
npm install -g netlify-cli
Once the netlify-cli is installed, go to the project’s root folder, and link your Netlify site to the folder. Click here to learn more about linking sites in Netlify.
netlify link
Once linked, type the following command to create a function.
netlify functions:create
You will see a list of predefined templates. Choose the “hello-world” template.
The function will be created in <project-root>/netlify/functions/hello-world/hello-world.js
Part II: Define the functions with logic
Here is an example of a Netlify function for Hasura's Actions, which checks if an email is present in the DB without exposing all the users to the client.
const axios = require("axios");
const hgeEndpoint = "https://example.hasura.app/v1/graphql";
const adminSecret = "adminSecret";
const handler = async (event) => {
let request;
try {
request = JSON.parse(event.body);
} catch (error) {
// Make sure you add code and message to errors. These will be shown in the hasura console errors.
let response = {
status: false,
code: "api/parse-error",
message: "error",
error: { message: "cannot parse input" },
};
return { statusCode: 400, body: JSON.stringify(response) };
}
if (!request.input.email) {
// Make sure you add code and message to errors. These will be shown in the hasura console errors.
let response = {
status: false,
message: "Please send email",
code: "input/undefined",
error: { message: "Please send email" },
};
return { statusCode: 400, body: JSON.stringify(response) };
}
let query = {
query: `
query check_user($email: String) {
users(where: {email: {_eq: $email}}) {
id
email_id
}
}
`,
variables: { email: request.input.email },
};
try {
let result = await axios.post(hgeEndpoint, query, {
headers: { "x-hasura-admin-secret": adminSecret },
});
if (result.data.users.length > 0) {
let response = {
status: true,
message: "success",
user: data.data.users,
};
return { statusCode: 200, body: JSON.stringify(response) };
} else {
// Make sure you add code and message to errors. These will be shown in the hasura console errors.
let response = {
status: false,
code: "user/not-found",
message: "No user found",
error: { message: "No user found" },
};
return { statusCode: 400, body: JSON.stringify(response) };
}
} catch (error) {
let response = {
status: false,
code: "api/fetch-error",
message: error.message,
error: { message: error.message, detail: error.toString() },
};
return { statusCode: 500, body: JSON.stringify(response) };
}
};
module.exports = { handler };
NOTE: Add the code and message to the response body.
These are displayed in Hasura’s GraphQL errors (whenever the API is returning an error in Hasura, they follow the GraphQL error standard).
The error in Hasura is displayed like this:
Part III: Add the function to Hasura using Actions
Once the custom business logic is created as an API using Netlify functions, add it to Hasura using Actions as follows:
- Login to your Hasura console and go to the “Actions” tab
- Click on the “Create” button
- Define the inputs and outputs of your API as shown below. (Learn more about the GraphQL inputs & outputs on Hasura)
- Add the endpoint of your Netlify function under the Handler.
Note: You can also modify the permission of the actions if you’re using role-based permissions.
Try out the Actions using Hasura’s GraphQL API Explorer
The success state on Hasura’s API Explorer from the Netlify functions will look like this:
The error state on Hasura’s API Explorer from the Netlify functions will look like this:
There are two error states
- When the user is not found with the requested email, you’ll see the following (User not found in DB error)
- When the email is not sent along with the request, you’ll see the following (Validation Error)
About the Author
Matheswaaran S is a full stack developer & Tech Enthusiast. You can learn more about what he does on his website, and connect with him on Twitter or Linkedin.