skip to content
oles.dev

Guide to Side effects in Hasura

/ 3 min read

When dealing with Hasura, it can quickly come to the side-effects of doing something less trivial than using only predefined upserts/inserts.

Most often, this comes to operations with databases, calling external API, or doing hefty validations.

Hasura offers multiple ways of achieving it, though these methods have their own advantages and use cases, here are them:

Postgres triggers

Hasura heavily relies on the database functionality, and in the case of Postgres, there is a possibility to achieve desired functionality with Postgres functions and triggers.

CREATE OR REPLACE FUNCTION insert_initial_album() RETURNS TRIGGER LANGUAGE PLPGSQL AS $function$
BEGIN
INSERT into album (artist_id, title) VALUES (new.id, 'first album');
RETURN new;
END;
$function$;
CREATE TRIGGER artist_after_insert AFTER
INSERT ON artist
FOR EACH ROW EXECUTE PROCEDURE insert_initial_album();

It is also possible to write validations on a Database-level

Pros: powerful flexibility, database-native functionality. Cons: calling a 3rd-party API is impossible. Maintainance and visibility of Functions and Triggers can be a hassle.

When to use: you are good with SQL, a believer in “you don’t need an ORM”. When to avoid: at large projects where observability of SQL can be an issue. SQL is not your strength.

Multiple Mutations in a Request

Given there’s a relationship established in Hasura, there’s a possibility to modify nested objects, for example:

mutation {
insert_album(objects: {title: "First album", artist: {data: {name: "Bono"}}}) {
returning {
id
artist {
id
}
}
}
}

This way, Hasura would create Album and Artist, and assign artist_id to the newly created Artist

Pros: out-of-the-box functionality, single transaction. Cons: lacking flexibility, if required to do more business logic on top.

When to use: fits your simple use-case. When to avoid: rarely, if it does solve the problem - use it!

Event Triggers

Another option is an Event trigger - webhook reaction on a database change

Creating an Event Trigger
Creating an Event Trigger

Pros: out-of-the-box functionality, ability to subscribe for particular CRUD events. Cons: it’s not a transaction.

When to use: effects, that doesn’t require integrity, for instance: analytics update, sending emails, notifications. When to avoid: no atomicity - operations are executed separately.

Hasura Actions

Actions is a mechanism for customizations, where custom queries or mutations can be implemented in webhook:

Creating new Hasura Action
Creating new Hasura Action

This action would instruct Hasura to invoke handler:

Example of webhook handler
Example of webhook handler

Pros: programming language runtime, flexibility, ability to do 3rd-party calls, and access to Database. Cons: cumbersome to set up handlers, types for every action needed.

When to use: you have to do a few manual operations, and you have a server in place (ie next) that can handle the requests. When to avoid: you need lots of side effects (then add Remote schema) or when it’s possible to use the abovementioned solutions.

Remote schema

Remote schema is a variation on Actions, but you bring your own additional Graphql Schema. Adding it to Hasura, will extend existing Schema with Queries/Mutations where you have full control.

Creating new Remote Schema
Creating new Remote Schema

Pros: easy integration with Hasura. Cons: you’d need to maintain your own GraphQL Server.

When to use: you already have a GQL server, or the application demands lots of non-trivial code. When to avoid: your app is small and doesn’t require a standalone GQL server.

Summary

These were 5 ways of achieving similar results in Hasura:

  • Postgres triggers
  • Multiple Mutations in a Request
  • Hasura Actions
  • Event Triggers
  • Remote schema

Each of them has its strengths and weaknesses, and you can use them successfully in combination. Hope this was helpful to pick the ones that suit you the best.