WunderGraph is the best Alternative to Hasura

cover
Jens Neuse

Jens Neuse

min read

My name is Jens, and I'm the Founder & CEO of WunderGraph, but most importantly, I'm a Developer, I always was, and still am. WunderGraph is a small but growing team, and as of today, I'm still working on the product.

So, what I'm telling you is not from the perspective of a CEO, but from the perspective of a Developer. I'm a big fan of Hasura and what they've done for the GraphQL ecosystem, but as a Developer, I never liked the way Hasura was designed.

At the end of the day, you can solve similar problems with either WunderGraph or Hasura. A detailed comparison would reveal some differences here and there, but the main difference is the developer workflow and architecture.

Let's break this down a bit.

A typical development workflow these days

  1. scaffold a new project
  2. make a few commits
  3. push to a remote repository
  4. hook up a CI/CD pipeline
  5. deploy to production

Next, you start iterating on the product. Modern Serverless platforms like Vercel allow you to deploy previews for each Pull Request. The flow looks like this:

  1. create a new branch
  2. make a few commits
  3. push to the remote repository
  4. open a Pull request
  5. preview gets deployed automatically
  6. your colleagues can preview the changes
  7. when you merge the Pull request, the preview gets deployed to production

How Hasura breaks this flow

For me, the described flow above is the holy grail of fast iteration. So far, our application was stateless, which we're now about to change. Let's add Hasura to the stack and see how the flow changes.

  1. scaffold a new project
  2. start Hasura locally
  3. start a local database
  4. use the Hasura Dashboard to configure the database and API
  5. Hasura is now working and can be integrated into your application
  6. make a few commits
  7. push to the remote repository
  8. deploy a production database
  9. deploy a production Hasura instance
  10. use the Hasura Dashboard to configure the production database and API
  11. deploy the application to production

There's something inherently wrong with the above workflow. The frontend application is build using the Serverless paradigm, while Hasura is a "Serverfull" solution.

Even worse, the primary option to configure Hasura is through the user interface. I'm aware that there are ways to configure Hasura through APIs, export and import configurations, and synchronize environments, but it's simply not serverless, and it's definitely designed for use with the Dashboard.

I know that some developers prefer to have a Dashboard and configure their APIs with point-and-click tools. However, as you scale your applications, you'll always want to configure environments through code. It's more predictable, it's repeatable, you can re-use code, and because you're putting this code into git, you get versioning and rollbacks for free. Finally, this code can live in the same repository as your application code, making the whole workflow a lot easier.

Things that can go wrong with the above workflow are mainly that you local environment diverges from the production environment, during deployments you forget to synchronize a change, and it might be hard to get the timing right when you have to deploy database migrations.

Next, let's look at the workflow for continuous development:

  1. create a new branch
  2. make changes to the local database
  3. make change to the local Hasura instance
  4. integrate the changes into the application
  5. deploy a staging database
  6. deploy a staging Hasura instance
  7. configure both staging database and Hasura with the Dashboard
  8. deploy the application to staging
  9. validate the preview
  10. merge the changes into the master branch
  11. migrate the production database
  12. make changes to the production Hasura instance with the Dashboard
  13. deploy the application to production

It's as good as it gets with a Serverfull solution. The main problem here is that Hasura is not build to support multiple branches. Additionally, the focus on Dashboard-driven-configuration makes it cumbersome to have multiple environments.

How WunderGraph blends into your existing workflow

Now let's compare this Workflow with WunderGraph, a truly Serverless solution, designed to support multiple branches and environments out of the box.

  1. scaffold a new project
  2. make a few commits
  3. push to a remote repository
  4. hook up a CI/CD pipeline
  5. deploy to production

When you scaffold a new project, WunderGraph is already integrated into the workflow with our Starter Kits. There's no Dashboard, the configuration of both database and the API layer is done with code. This code is part of the repository, so it can be picked up by CI/CD pipelines automatically to deploy the frontend, migrate the database, e.g. with Prisma, and deploy the API layer.

You also don't have to integrate WunderGraph into your application. WunderGraph automatically generates a type-safe client to access your API, it's a single configuration parameter, and you're done with the integration. The generated client also handles the authentication flow and can be used to upload files. It's a production-grade end-to-end solution.

The best, fastest, and easiest to maintain code is the code we don't write. WunderGraph strives to remove as much code as possible from your application. This means you can deliver faster and you have less to maintain.

With Hasura, you've got to think about how you want to use your API. Do you lock it down? What client should you use? How do you add authentication?

Next, let's have a look at the workflow for continuous development:

  1. create a new branch
  2. make a few commits
  3. push to the remote repository
  4. open a Pull request
  5. preview gets deployed automatically
  6. your colleagues can preview the changes
  7. when you merge the Pull request, the preview gets deployed to production

WunderGraph supports branches and environments out of the box. A different branch, a different environment, it's all just code. You don't have to manually configure anything with a dashboard, just change a few lines of code and git push.

As you can see, WunderGraph doesn't really change the workflow, whereas Hasura makes it a challenge at scale. Now, let's look at security.

A different perspective on security

In terms of security, both WunderGraph and Hasura follow a different paradigm.

Hasura exposes a GraphQL API and allows you to manually lock it down. By locking it down, they mean that you can create allow-lists of GraphQL Operations for production, but client and server still communicate using GraphQL over HTTP POST.

At WunderGraph, we've made an important observation of how developers use GraphQL APIs. When in production, almost no one changes their GraphQL Operations, they are static. So, if you're not changing your GraphQL Operations in production, why do you even expose GraphQL at all? Why not use GraphQL during development and replace static GraphQL Operations with JSON-RPC?

That's exactly what we're doing. Each GraphQL Operation is automatically compiled into a JSON-RPC call, while were also generating a type-safe client to access this RPC Endpoint.

So, WunderGraph looks like GraphQL, feels like GraphQL, but uses JSON-RPC over HTTP at runtime. This means it's more efficient, we're sending fewer data, and it's much more secure because the GraphQL API is not exposed to the public.

Why do we have to lock down a vulnerable API that shouldn't have been exposed in the first place?

Hasura breaks with the Idea APIs in general

Another aspect I'd like to discuss is that Hasura is breaking with the idea of APIs. Here's a quote from the API Mandate from Jeff Bezos from 2002:

  1. All teams will henceforth expose their data and functionality through service interfaces.
  2. Teams must communicate with each other through these interfaces.
  3. There will be no other form of interprocess communication allowed: no direct linking, no direct reads of another team’s data store, no shared-memory model, no back-doors whatsoever. The only communication allowed is via service interface calls over the network.

Hasura automatically introspects your database, generated a GraphQL API from the tables, and exposes it to the public. You're not directly sharing the database, but your API actually leaks the implementation. So, while you're using GraphQL, you actually are exposing your database, even if the interface is different.

This, by my definition, doesn't live up to the idea of APIs. APIs should hide the implementation, and expose a public interface. When you change a database table, your Hasura API will change as well.

This is a feature in the first week of your project, but it becomes a burden over time. If other teams and companies depend on your interface, but your interface actually represents your database, you're stuck in that you're not able to make breaking changes to the database schema.

Additionally, a GraphQL API, generated from the database, is not really an API that you could share with anybody. APIs need to be designed around specific use cases, activities, and interactions. If the tables in your database dictate the shape of the API, it's very unlikely that the result of the API will be useful to anyone who doesn't fully understand the data model of your database.

With WunderGraph, you can generate a GraphQL API from your database as well, but we're not exposing it. We expose a JSON-RPC API, with an OpenAPI Specification and generated clients. You can use the database generated API internally, but the public API will be defined by yourself.

Your users will get a Postman Collection, or a generated client/SDK, which really represents the possible use cases of you API, not just tables.

Remote Schemas and API Composition / Federation

Speaking of tables, your company is probably not built on top of a single database. You might have multiple databases as well as numerous internal and external APIs, REST, GraphQL, Apollo Federation, and so on...

To solve this problem, Hasura added a feature called "Remote Schemas". Remote Schemas allow you to attach other APIs to the initial database-generated API. You attach a Remote Schema by configuration in the Dashboard.

There are two problems with this approach. First, Hasura requires you to have a database in the first place. But, what if I work in an environment where I don't want to have a database but simply want to use APIs?

Second, and that's probably the biggest problem here, the Remote Schema configuration is static, when it needs to be dynamic. Let me explain this in a bit more detail.

When you combine two APIs, you have to configure certain rules to make sure that the two APIs are compatible. For example, you have to make sure that there are no naming collisions. You might also want to set up links between the two APIs, e.g. to be able to join data across them.

The way you configure this in Hasura is by defining this in the Dashboard, for the current state, and that's the problem. APIs change all the time, so the Remote Schema configuration shouldn't be static. Instead, it should be defined like an arrow function.

So, with the Dashboard approach, you can only configure the Remote Schema once. Whenever any of the APIs change, you have to reconfigure the whole thing. If you add links to fields, you have to link them again after re-adding the Remote Schema.

With the WunderGraph approach, adding a Remote Schema means that you're writing some code. Adding a link to a field also works by writing some code. This code can run over and over again, using continuous integration. So, the changes you've configured will always be applied automatically. You don't have to re-configure it over and over again.

In a world of constantly changing APIs, I don't believe in a tool that's not designed for this common use case. I think, Hasura has come a long way, but it's really visible that it was designed to expose your database, and not to compose and integrate APIs.

Summary

Some developers might like the Dashboard approach more, and I respect that.

But for those, who want to scale their architecture, automate as much as possible, and abstract away mundane repetitive tasks, I can definitely recommend WunderGraph as a viable alternative.

Stay up to date

The latest WunderGraph news, articles, and resources, sent to your inbox.

© 2022 WunderGraph, Inc. All rights reserved.