How to send email with GraphQL or Hasura
Tags: graphql, beginners, tutorial, programming
Published: 2022-10-06 08:50:24

In this article I will explain to you how you can send an email with [GraphQL](https://www.graphql.com/) or Hasura. The solution Hasura suggest, that is based upon Stored Procedures or Database Functions is (obviously) sub-optimal, since it implies adding business logic into your database. I’m not even sure about how to comment on this, so I’ll avoid sharing my opinion about this “solution” to stay polite. However, by creating an HTTP API gateway, that “intercepts” our invocation to your GraphQL endpoint, we can actually easily send emails, without changing **anything** in our frontend code, besides the URL we’re invoking.

This is easy because of that [Hyperlambda](https://aista.com/hyperlambda/) has great support for creating such API gateways. So let’s look at a video where we create such an endpoint in some roughly 10 minutes.

{% embed https://www.youtube.com/watch?v=Zvklionkzo0 %}

The basic idea of our code is to first extract the [JWT](https://jwt.io/) Bearer token, for then to forward it to our GraphQL endpoint at Hasura. Then we add whatever payload the client supplied to us to our **[http.post]** invocation going towards Hasura. When the invocation returns, we return to the client whatever Hasura returns to us. At this point, the only remaining question is if we should send the email before or after invoking the GraphQL endpoint. We could expand upon our gateway easily by for instance checking if Hasura returned a success status code or not, but that’s an exercise I will leave to the reader.

To get started, first sign up for a [low-code Hyperlambda cloudlet](https://aista.com/) here. Then watch the above video, and find the code at the bottom of this article. Notice, I haven’t actually tested the GraphQL send email logic, since I don’t have a Hasura project, and I personally for obvious reasons prefers Hyperlambda – But I suspect it should work out of the box as is.

```
// Accept any arguments.
.arguments:*

// Validating user is giving us a valid email address.
validators.email:x:@.arguments/*/email

// Retrieving JWT Bearer token to transmit to Hasura.
request.headers.get:Authorization

// Lambda object responsible for sending our email.
.send-email
   mail.smtp.send
      message
         to
            foo
         subject:This is subject
         entity:text/plain
            content:Hello world from Hyperlambda HTTP API gateway.

/* Changes the "to" parts of our send email invocation
 * to whatever argument we're given by client.
 */
set-value:x:@.send-email/**/foo
   get-value:x:@.arguments/*/email
set-name:x:@.send-email/**/foo
   get-value:x:@.arguments/*/name

// Forwarding arguments given to endpoint to invocation to Hasura
add:x:+/*/payload
   get-nodes:x:@.arguments/*

// Invoking Hasura's GraphQL endpoint.
http.post:"https://my-app.hasura.io/graphql-endpoint"
   headers
      Authorization:x:@request.headers.get
   payload
   convert:true

// Send the email AFTER invoking GraphQL endpoint.
eval:x:@.send-email

// Return result to caller.
add:x:+
   get-nodes:x:@http.post/*/content/*
return
```

And that’s it, 46 lines of code, allowing you to send an email as you’re invoking your Hasura GraphQL HTTP endpoint :)

Notice, you can of course apply any business logic you want to apply in your gateway. In our above code for instance, we’re validating that the email argument passed in is a valid email. In future articles I will elaborate on how to actually accomplish this, by creating additional interceptors, allowing you to apply whatever business logic you want to apply, and intercept your GraphQL endpoints as you wish.

Notice, this solution obviously works equally well for Supabase and their PostgREST API, and becomes a much simpler to understand solution for most also compared to their “edge functions”.

## Conclusion

Of course, at this point the obvious question would become

> Why on earth do I need GraphQL and Hasura when I’ve got Hyperlambda?

I have absolutely no intelligent answer to the above question, and I suspect there doesn’t even exist an intelligent answer to it - However, if you've got an answer, feel free to enlighten me in the comments below ...