Avinash Moondra spoke last year at HasuraCon'20 on how to shift from Rails to Hasura and what the difference and similarities are.
As HasuraCon'21 is almost here, we thought it would be the perfect time to take a look back on all the amazing talks by our amazing speakers from 2020!
Here's Avi's talk in video form:
And below is a text transcription of the talk for those who prefer reading! (The text is slightly paraphrased and edited here and there for clarity's sake.)
Hey, everyone, this is Avi.
A bit about me
I will be speaking on the topic of shifting to Hasura - lessons from a Rails developer. And I'll just get right into it because 10 minutes is a short time. So just some context on me. I'm a software engineer that's worked mostly in web startups so far.
Rails vs Hasura (but not really!)
Having used both Rails and Hasura, in fast-moving production environments, my goal here today is to help y'all shift your mindset from Rails to Hasura, without getting into which is better. So we'll highlight some major architectural differences and map some shared concepts, and hopefully, at the end of it, you'll have less surprises and more confidence as you get started with Hasura. Alright, let's get into it.
Shifting from Rails to Hasura: Shift #1 - Monolithic MVC vs Event-Driven SOA
So I'm gonna go over a couple of different what I call shifts.
And the first one is, I would say the most important going from the Rails monolithic MVC architecture to a serious event-driven sort of service-oriented architecture.
So Rails covers, and seemingly always will, more web development surface area than Hasura. And not just because it has a 13 years head start. It sort of prides itself in the monolith, you know, everything from routing a request to fetching the data for that request and displaying that data in a user-friendly way, serving up the page, and everything else.
Hasura, on the other hand, is a backend as a service, and it will cover sort of the common and exhaustingly sort of boring ORM and API server requirements, but you know, bring your own friends’ event handlers and authentication table. It will come prepackaged with you in a similar value integrated systems sort of way with a programmable permissions framework, subscriptions, and then most recently scheduled triggers alongside triggers.
Now, I kind of anticipate Hasura will quickly eat more of these common back-end concerns and abstractions. Anything from inbound/outbound email, database choice, and the management of the database for replicas and partitions is only two years old.
And while Rails has sort of this, you know, equivalent abstractions to say, as subscriptions or triggers like action cable and active job, be it with, you know, Sidekick, or Rescue or whatever, that I would argue that these capabilities they integrate well with Rails, but are not native to its architecture.
And this is a result of a sort of fundamental difference in the architecture of the data flow between Rails and Hasura. I think that's worth taking a closer look at.
So let's first take a look at Rails in a sort of model view controller fashion.
A controller receives RESTful requests from the outside world, the router interacts with the model to update the application state and prepares the appropriate view to the user. Side effects are sometimes handled inline. At other times, they're pushed to job queues. Another thing to note is the web workers, the job workers, and the pub/sub workers all run from the same shared codebase.
Now we can, sort of, compare that to Hasura, whoops, compare that to Hasura, which you can see the request and the response cycle and the pub/sub share the same, sort of, specifically GraphQL API interface and infrastructure, and all the side effects are persisted as events to be processed asynchronously. And to process those events, webhooks, and other custom, sort of, business logic that you have, you're gonna need some services outside of Hasura to do that, which kind of lends itself to this sort of service-oriented architecture.
And pub/sub and inventing, in general, is brought to the forefront to make an event-driven architecture. And a sort of useful way of looking at this difference is from a functional programming perspective, kind of.
This is a screenshot from one of my favorite talks by Martin Kleppmann, and, kind of, what it covers is basically a story, that story that you can tell that the browser page, what the browser paints is just a function of what the template renders, which is just a function of the JSON data from your API, which is just a function of the relational data from your database.
So if the entire application is just a function of our data, then we can run that function every time a state change has been made. And so that sort of mindset actually, is very incorporated into the core of Hasura.
Actually, they describe the pattern as a three-factor app, which kind of has some analogies to Redux. And so you can check out the three-factor app for some more details on that. But I would also emphasize that GraphQL here is, not the difference. It's, you know, Firebase would be the restful equivalent, more so that, Rails centers around the sort of concepts of model view controller, MVC, REST on a request and response like, out and back.
And Hasura kind of centers more around an event-driven architecture, GraphQL, and subscribe and notify more like a loop. And so that I would say is like the biggest difference and fighting the framework in either case, is sort of going against the Rails way or the Hasura way, you'll kind of find yourself having a less happy experience with either framework if you sort of don't incorporate these opinions or these kinds of fairly opinionated pieces of software.
Shifting from Rails to Hasura: Shift #2 - REST vs GraphQL
So let's now jump to a second shift here, which is sort of REST vs GraphQL, and obviously, you'll be using GraphQL, when working with Hasura, and fighting that is pretty futile. And it's not just any GraphQL API, I'd call it sort of this perfectly defined API for you know, both, you know, it's auto-generation, we didn't write most of the code, but also for its expressiveness and compatibility with sub specifications like Relay.
It also forces a sort of built-in command query separation, especially when workflow in your domain isn't fitting into CRUD, you can kind of safely set aside your sharpened Ruby knives when you're moving from Rails to Hasura.
And so, on the left here, of course, is like your classic Rails, sort of, paths to doing different sort of actions. And on the right, is the query fields that you get just out of the box from Hasura. And there before diving deeper into those, it's important to note that, like, you can implement GraphQL in Rails, of course, really, anything is possible in Rails, and yeah, that's possible with the GraphQL Ruby gem plus API only controllers. But it's just not at the forefront of the Rails way, like REST and sort of CRUD is. And this is just a screenshot pulled from, you know, their Getting Started guides, of course.
And instead of discussing further into how I would map you know, the left side here and the right side - I think there's plenty of coverage on how to shift your mindset from REST to GraphQL or REST-based CRUD to GraphQL - I wanted to, sort of, talk about two general points that relate to how applications talk to the database in the web world.
And one of those, of course, is authentication, it's like a super important part of how clients make requests to servers. And in Rails, you have action dispatch session, or this sort of loved, hated, devise gem when working with Rails, but in Hasura, authentication is totally handled outside and they have just built-in ways to plug into it. And those standard ways are webhooks and JWTs or JSON Web Tokens.
This position is, kind of, generally in line with the trend of the vendorisation of, sort of, authentication. And there's plenty of tutorials on Auth0, Auth Guardian, AWS Cognito, kind of any integration that you're looking for.
The other bit is I wanted to talk about is in Rails, if some flow isn't feeling RESTful, or just you know, you want to, you need to get around the convention, it's really easy, you just, you just write more code. And it's pretty straightforward.
But Hasura, we didn't write Hasura so how can we customize it? There are a couple of options, but custom actions is your simplest escape hatch when pushing up against the limits of CRUD GraphQL API, or you need to depend on, sort of, some libraries or, or some custom conditional logic.
Some simple examples here would be through generating or returning a JWT, from an unauthenticated Hasura query field, right. So this is setting up your authentication endpoint. Or using the result of one complex mutation to make another. And it's not always perfect.
Sometimes you have to work a little harder when you don't have a server that you wrote yourself. And an example here is getting what's the current time on the server and, and this is not as straightforward. You have to create a view here on in your Postgres database, and just get the now timestamp and return that as a view and expose that through the API, but it's all possible. And for the most part, CRUD will get you so far along the way, especially in the GraphQL context and the expressive API that they've given you.
Shifting from Rails to Hasura: Shift #3 - ORM vs ?
The third shift that I wanted to talk about was true of the ORM, which is an Active Record, is one of the most important, sort of, parts of Rails - it's the M in the MVC, and regardless of whether you're rolling your own front end or using GraphQL, you’ll definitely be generating migrations, building and querying models or configuring validations and callbacks.
So where is the ORM in Hasura?
And the catch is there isn't one, at least in the same shape, size, or form. In Hasura we kind of experienced the ORM and the API layer as one. And from a CRUD perspective, Hasura GraphQL API provided out of the box is equally, if not more expressive abstraction over SQL and we can, kind of, look at some examples here.
On the left side, here’s some pretty standard Rails Active Record code. And on the right sort of the mapping that you can get, sort of, find, find by select filters, joins, nested, where clauses that are doing much more complex joins that you can, sort of, struggle to do with an Active Record, create or update or find your update, or find or create, update all pretty out of the box given to you from Hasura.
And so that covers CRUD, what about all the other good parts of Active Record? I think there's some listed here, which, I won't get into all of them. But migrations, for example, largely inspired, I think, by Rails on the Hasura side, is supported out of the box. And instead of using a CLI and a DSL, that's like borderline ergonomic, instead, you get a user-friendly UI, and you can kind of generate all the up and down migrations as you need.
The other bit is around JScripting, let's pick that as an example, just from the list here. And it's probably what I'll miss the most from Rails, and Ruby, and while GraphiQL like the interface where you can kind of type queries and test out and edit one-off queries, and from the Hasura UI, you know, the ability to like just jump into a Rails console, it's something I always have open, while developing in Rails and to kind of like, you know, get around this, I think there's two, kind of, at least one saving grace is that the backfill scripts or seed scripts in Hasura all communicate over HTTP API, so at least there's only one system that you had to learn versus learning, you know, the API or end ORM, at the same time.
And the other saving grace, as a complement to that, is Hasura is super fast. So you wouldn't have to really worry about performance here. In general, I think, regarding the ORM and the approach that Rails and, sort of, Hasura takes, I wanted to sort of highlight this as a key, I think, like, tendency difference between the two technologies: abstraction of the database.
I think Rails, you will see, tends to hide it from the user and protect you from it. And Hasura tends to say, no dive in, and kind of exalts to sort of embrace the database. Actually, a lot of the features about how that powers Hasura is very database-native features.
Shifting from Rails to Hasura: Shift #4 - Pillars
The last shift is hardly a shift at all. And it's talking about the pillars at the core of these technologies. And I think it, it's hardly a shift at all because when I, when researching this topic, I went back to reread, sort of, this controversial Rails doctrine that outlines the most important pillars, that led to the rise of Rails, and it's kind of guides, it's continued development on the left here, the nine, sort of, principles.
And I was surprised to find Hasura shares, like, many of these foundational pillars, you know. Everyone is, Hasura is built to make it super easy to program then feel pretty good while programming in it, and sort of, increase the productivity of the developer.
I think the, probably the, two major differences here between Hasura and Rails, is “no one paradigm” and “provide sharp knives”.
I think, “no one paradigm”, think because Hasura pretty strongly is tied to GraphQL and the event-driven microservices approach. It's also a back end as a service versus a standing sort of web development framework.
And I think the other one is, that I think, differs a little bit as providing sharp knives. And I think Hasura, you know, instead pushes this codeless, pre-cut approach with auto-generation - and your custom actions here is a counterexample - but it focuses on the common and the plumbing, the same basic toolbox leaving you to the rest, either with a built-in escape hatch, or just complete freedom.
And so with that, I kinda wanted to just give a summary here of different shifts that you can make, and kind of help you, sort of, move from this monolithic MVC REST, CRUD based, sort of model to a more event-driven, service-oriented architecture that, sort of, revolves around GraphQL.
So thanks for tuning in! And feel free to get in touch with any links here:
And I hope that's helpful as you make the shift to Hasura. Thanks!