This content originally appeared on DEV Community 👩‍💻👨‍💻 and was authored by Thomas Hansen
HTTP gateways are incredibly interesting. For instance, you can easily create a Hyperlambda HTTP gateway that adds business logic to Supabase or Hasura, to intercept the original endpoint, and inject business logic before or after the invocation to your originally wrapped GraphQL or PostgREST endpoint. This has use cases such as for instance.
- Add business logic to GraphQL endpoints, such as those exposed by Hasura
- Add business logic to PostgREST endpoints, such as those exposed by Supabase
- Add HTTP caching to optimise your original HTTP endpoint
- Apply authorisation to endpoints originally not having authorisation
- Log error invocations
- Etc, etc, etc
With for instance Hasura, the preferred method of implementing business logic is one of the following according to their FAQ.
- Event Triggers
- REST APIs
- GraphQL APIs
- Stored procedures or functions in your database
Ignoring event triggers and stored procedures, plus functions, due to that these methods arguably are the very definition of bad architecture resulting in the “big ball of mud” – This leaves us with GraphQL APIs and REST APIs. Since the purpose of Hasura is to simplify things for you, the GraphQL API and REST APIs gives you little or nothing. However, there exists a 5th method that is not documented at Hasura’s website; HTTP gateways!
This allows you to intercept the original HTTP endpoint, forward the payload to “whatever”, and inject your own business logic either before or after invoking the Hasura GraphQL endpoint, or Supabase PostgREST endpoint. Some use cases for this might be for instance.
- Validate data before allowing the GraphQL endpoint to be invoked
- Send emails as some GraphQL endpoint or PostgREST endpoint is invoked
- Apply logging if the GraphQL or PostgREST endpoint invocation fails
- Apply either server side cache, or HTTP cache for your endpoints, to optimise execution of slow queries
- Etc, etc, etc
The by far easiest way to achieve such a thing, is to create your HTP gateway using Hyperlambda. In the following video I am demonstrating the idea. Notice, you can find the code I am creating in the video at the bottom of this article.
This allows you to easily add business logic to Supabase or Hasura, through interceptors, resulting in that you can now easily “inject” business logic, both before and after invoking your original endpoint. No need for Supabase’s “edge functions”, learn TypeScript, or NodeJS. No need to add stored procedures to your database to put business logic into it. No need for slow HTTP REST endpoints invoked by your Hasura GraphQL implementation as “extension methods”, etc, etc, etc. And, this allows you to validate data before passing it into either Supabase as PostgREST arguments, or Hasura as a GraphQL payload.
As an additional bonus, this allows you to “transform” the weird (at best) HTTP POST requirements Hasura forces you to apply due to GraphQL typically forces you to implement your read invocations as POST invocations.
Frontend CRUD generator wrapping your Hasura or Supabase project
In addition, if you create a strongly typed Hyperlambda endpoint, you’re also able to generate meta data on your GraphQL endpoints, creating CRUD endpoints, that you can all of a sudden generate an Angular frontend for using Aista. To understand what I’m talking about, realise the following is easily achievable for you using Aista for both your Hasura and your PostgREST servers, due to Hyperlambda’s ability to use meta data to generate Angular frontends.
I will go into depths of the last point in later articles, but realise that as long as you can correctly “type declare” your Hyperlambda endpoints, Aista can automatically generate a CRUD frontend for you. You can try one such frontend here. So all of a sudden, you can now generate frontends 100% automatically for your Supabase and Hasura projects.
Of course, at this point the natural question becomes as follows; If you’re using Hyperlambda and Aista as an HTTP gateway, and you’re creating strongly typed HTTP APIs, wrapping your existing Hasura and Supabase projects, and you’re applying all your business logic in Hyperlambda – Why not switch entirely to the automatically generated CRUD API that Magic generates? To understand the latter, please read up more about how Aista automatically generates CRUD APIs for you, wrapping your existing or a new database.
However, sometimes when you’re stuck in “legacy land”, extreme measures needs to be applied to slowly change over time. And for a period, the above Hyperlambda HTTP Gateway solution might just be exactly what you need, to slowly transfer from legacy GraphQL code or legacy PostgREST code, to a modern and scalable stack such as Hyperlambda.
Code
Below you can find the code I use in the above YouTube video.
gateway-original-1.post.hl
.arguments
name:string
auth.ticket.verify:root
strings.concat
.:"Hello "
get-value:x:@.arguments/*/name
unwrap:x:+/*
return
result:x:@strings.concat
gateway-original-2.post.hl
.arguments
name:string
strings.concat
.:"Holla there "
get-value:x:@.arguments/*/name
unwrap:x:+/*
return
result:x:@strings.concat
gateway-simple.post.hl
.arguments:*
// Add all arguments into [http.post] invocation!
add:x:./*/http.post/*/payload
get-nodes:x:@.arguments/*
validators.string:x:@.arguments/*/name
min:5
max:10
// Invoking original endpoint we are now wrapping.
http.post:"https://tiger-polterguy.gb.aista.com/magic/modules/faq/gateway-original-2"
convert:true
payload
if
and
mte:x:@http.post
.:int:200
lt:x:@http.post
.:int:300
.lambda
// Example of how to send an email using Hyperlambda.
.mail.smtp.send
message
to
Thomas Hansen:thomas@gaiasoul.com
from
Testing Gmail:testing.anarchy@gmail.com
subject:This is subject
entity:text/plain
content:This is body
else
lambda2hyper:x:@http.post
log.error:x:-
// Returning result of original endpoint invocation to client.
add:x:+
get-nodes:x:@http.post/*/content/*
return
gateway.post.hl
.arguments:*
// Validating length of name argument
validators.string:x:@.arguments/*/name
min:5
max:10
request.headers.get:Authorization
// Add all arguments into [http.post] invocation!
add:x:./*/http.post/*/payload
get-nodes:x:@.arguments/*
// Invoking original endpoint we are now wrapping.
http.post:"https://tiger-polterguy.gb.aista.com/magic/modules/faq/gateway-original-1"
convert:true
headers
Authorization:x:@request.headers.get
Content-Type:application/json
payload
// Sanity checking the result of our invocation.
if
and
mte:x:@http.post
.:int:200
lt:x:@http.post
.:int:300
.lambda
// Returning result of original endpoint invocation to client.
add:x:+
get-nodes:x:@http.post/*/content/*
return
else
// Logging an error!
lambda2hyper:x:@http.post
log.error:x:-
throw:Something went wrong as you invoked your HTTP endpoint
status:500
public:true
Thank you for reading, I hope it was helpful to you :)
This content originally appeared on DEV Community 👩‍💻👨‍💻 and was authored by Thomas Hansen
Thomas Hansen | Sciencx (2022-10-05T18:37:24+00:00) Add business logic to Supabase or Hasura. Retrieved from https://www.scien.cx/2022/10/05/add-business-logic-to-supabase-or-hasura/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.