Hasura Actions using Netlify Functions for Custom Logic
Tags: graphql, api
Published: 2022-11-25 15:22:47

---
title: Hasura Actions using Netlify Functions for Custom Logic
published: true
date: 2022-11-16 15:07:02 UTC
tags: graphql,api
canonical_url: https://hasura.io/blog/hasura-actions-using-netlify-functions-custom-logic/
---

![Hasura Actions using Netlify Functions for Custom Logic](https://hasura.io/blog/content/images/2022/11/hasura-actions-custom-logic.png)

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](https://hasura.io/docs/latest/actions/index/).

### 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](https://www.netlify.com/products/functions/) 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_](https://hasura.io/docs/latest/actions/rest-connectors) _to Hasura’s GraphQL schema._

## **Part I: Create a Function in an app**

To create a function in the app, install the [netlify-cli](https://docs.netlify.com/cli/get-started) 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](https://docs.netlify.com/cli/get-started/#link-and-unlink-sites) 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:

![Hasura Actions using Netlify Functions for Custom Logic](https://lh6.googleusercontent.com/ssXJTbpctJyttmAWDF0pDE2MNS2zlG1ORflEio3Dqpq8gW07sp50NQ_JqOTBjuXfkbEuX6oLTOvh1s0_TAei3p4MyoTJQiv_gkraZsrQzjVwXvwYgiucDWgZRInk1Oa6MsshQ1fswoK_6FomPpykucoEZOvJJBLxvOhi8An60I3CYdNjo2HhmEdaxE6YUg "Error state in Hasura GraphQL")
_Error state in Hasura GraphQL_

**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](https://hasura.io/docs/latest/actions/types/index))
- Add the endpoint of your Netlify function under the Handler.

![Hasura Actions using Netlify Functions for Custom Logic](https://lh4.googleusercontent.com/c09_kYvMRI1vW06rWeGraLyH23lIsPNh1L1ohNKckY_dS5JRpADWCaZIUqR0ZG_w3MO0zmGzeLYSOF_2AZWgME7NpIV9S0NF9t1ZBJ8R98b9qncDdhAfNr3O2-JaJiQbM7pE2o64E508hLSabZTmKJiNsqlI37c2K6eRdVAWgKnfSxzXblWNA3cCOUZWzg)
_Creating an Action_

**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:

![Hasura Actions using Netlify Functions for Custom Logic](https://lh3.googleusercontent.com/xLSQ1ElSCEmxqptt-Sk6_6oOi8K44nM7GbHW8qYsNo9vOCKAWfbnULzh99JDyjz1x0pe3h7Efa8e5u2l1ac2iySN5Rx2dJdSqVoGJbYQOYxYwWFH5dJKZ5WA3YQOJSpYwFjTiG_TKEzVm-H5ekU72mFyChVcX6MO0ErvbumUQTqTmAqrhLMnoRbN7C-nWA)
_Success state of an action_

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)

![Hasura Actions using Netlify Functions for Custom Logic](https://lh5.googleusercontent.com/nFGp3TPeun3YsHi7AgZ1pabqS8z9t4tTP0GJcsFSmMM0ul_-JFzBbg4Do1tkgA1Af0g_yCsJPzzaTSru7s6U-grHAxbMJykbXpesWhHkJgY2WGryBlgKMwbLkTJtWtm_pTV8jAmDvEpIV2L8O1EYkzQSBSmpB1xYA_bpt8z6GQQxynhFbFs3z1TJfD6Bmg)

- When the email is not sent along with the request, you’ll see the following (Validation Error)

![Hasura Actions using Netlify Functions for Custom Logic](https://lh4.googleusercontent.com/gYkdLQavolkRoIsC7SjgdXe0jodUmWF2PuK7mGAqQsiWPrtKV2S7930frRhZUzEkVaQYrU3LVdNGNAVNJTmLYN_cpV2gYRKo0arjShBj4ljiD1tm7ZNhCR75u0XXcYyzSKv4HvJAgYH7nQf7efpnFta40keKJggXtrP5rg4EoHHcjM6pyVM32saOqEulIA)
_Input not given / undefined error_