Hasura raises $9.9M to simplify GraphQL
techcrunch.com
techcrunch.com
After going through multiple different stacks such as MeteorJS, Firebase, building my own REST/GraphQL API etc. Nothing really felt right.
That was until I found out about Hasura.
I actually had to assemble a quick meetup at the co-working space I was on (true story) to show everybody this software. Hasura Tweet: https://twitter.com/HasuraHQ/status/1068145251267895300?s=20
They were all amazed and many use Hasura in production today in their apps.
For myself, I was so enthusiastic about Hasura and I always had Google Firebase in the back of my mind. Google Firebases DX is really good. I really liked it. But I did not like their tech (noSQ / REST / vendor lock-in).
So, I decided to start https://nhost.io.
Nhost is like Google Firebase but with PostgreSQL and Hasura (GraphQL). Right now providing database, API, auth and storage. Here is a short demo: https://www.youtube.com/watch?v=MWB5RXzlJM8
I feel very fortunate to be able to work with such awesome open source software and the success of Hasura makes me so happy, because they are, as mentioned in the comments field before me, a game-changer!
https://hasura.io/blog/building-an-offline-first-web-app-wit...
It's this developer experience I want to mimic with Nhost. By providing a managed backend with simple to use js-sdk (https://github.com/nhost/nhost-js-sdk).
We chose this because :
1.Open source (no vendor locking although now i'm sure if i had to move from b4a it would be a small PITA 2. Ready to use 3. actively maintained (graphQL have been implemented although we have not used it yet) (3)
My question is : should i invest time on discovering nhost for my next POC ?
(1) : https://github.com/parse-community (2) : https://www.back4app.com/ (3) : https://docs.parseplatform.org/graphql/guide/
1. SQL (Thanks PostgreSQL)
2. Instant realtime GraphQL (Thanks Hasura)
3. Zero vendor lock-in
This is wrong. For basic features that are absolutely needed for a real-life app you will need the "Pro" hasura license.
Amazing at first, but quickly fell apart when I had to implement any sort of meaningful business logic.
2. Actions - https://hasura.io/docs/1.0/graphql/manual/actions/index.html
3. Remote Schema - https://hasura.nhost.io/console/remote-schemas/manage/schema...
I know Hasura is actively working on this exact issue and they just released Actions (second option) and I think we will start to see a standard/best practice approach to business logic soon.
@elitan - just checking nhost. Features sounds promising.
Did you use hasura for building nhost's backend as well ?
Do you know why Hasura don't provide a managed service themselves?
Also, I wonder if Hasura will eventually move to a MongoDB-like license.
Hopefully, we will be mentioned in the documentation for Hasura.
Hasura does provide a hosted version (EDIT: not a hosted version) (Hasura Pro). You can read more about it here: https://hasura.io/hasura-pro
1. We're working on adding nhost to the Hasura docs as a deployment guide for when you'd like authn + files + hosted postgres in one neat place. Johan just did a slick demo in the community call right now :)
2. To clarify: Hasura Pro is not a hosted version of Hasura. It's an agent that is added to wherever Hasura happens to be running for enabling monitoring/testing features.
i suspect that mainly applies to venture backed businesses - it could be a great lifestyle biz
Together with Nhost's auth system and Hasura, it's easier than Firebase.
I'm comparing you to Heroku, sorry if that's not your ideal comparison.
I think you need some different price points; the $4/month is great to get started, but the $40/month with 15M just really pales in comparison with Heroku's $50/month for 64G... particularly when I compare it with your $139/month for 5G of database.
Thanks for a great looking product, though!
How do we add business logic ?
Folks @hasura, where do we learn about haskell ? any helpful pointers much appreciated.
1. Actions - https://hasura.io/docs/1.0/graphql/manual/actions/index.html
3. Remote schemas - https://hasura.io/docs/1.0/graphql/manual/remote-schemas/ind...
Awkwardly. Good luck
Check out the result here: http://www.hedgecheap.com
Which parts of Firebase is Nhost replacing?
Next on the road map: Cloud Functions, Hosting, Crash Reporting.
We try to go from the core and outwards. Hope it makes sense.
Thanks again!
https://www.graphile.org/postgraphile/
There are plenty of "REST API in a box" solutions as well:
https://github.com/PostgREST/postgrest
I love the Hasura folks too, and they're a funded startup rather than a one-person operation relying on donations. Open source is hard, and benjie (creator of graphile and many other things, he's incredible) could use some help: https://www.patreon.com/benjie
But in my case it was because my existing database is a fairly complicated beast with a lot of updating through stored procedures on views. Hasura wanted to have control of what is happening in the database and there was zero chance that it would agree with the existing triggers about what should happen or how it worked. (Example of an issue, Hasura wants to own the view and view structure so that it can make real time subscriptions work.)
By contrast Postgraphile was happy to be pointed at a schema of views for just what it should see, read a https://www.graphile.org/postgraphile/smart-tags-file/ and believe what it was told there about the underlying database structure, and then expose an API that showed what I wanted it to show without breaking what was under the hood.
Unless I’m grossly misunderstanding, none of that is correct in the slightest!
Hasura doesn’t assume _anything_ about your table or view structure. Hasura will never interfere with your existing stored procedures either. At most hasura will refuse to track some items in your schema because they don’t adhere to the GraphQL naming spec. But hasura doesn’t own and control tables/views/triggers at all!
I’m actually really confused and surprised because this sounds exactly like the opposite of what Hasura does and what it was designed for, ie work with existing databases instantly.
I’d love to understand this in more detail and see if there was actually an issue and what it was. It's an important thing for us to look into and fix and would deeply appreciate your notes! Is there someway i can reach you?
Anyways here is the use case. We have a table named model.nodes. We have various model.foo_detail tables. And views named model.foo. Every foo is a node. (Clearly this schema predates our interest in GraphQL...) We have triggers on the foos so that they can update the underlying combinations of tables correctly, and also keep an audit log. We have an external CMS running off of a different architecture which handles authentication.
There are additional complications that I am not going into, such as the fact that every client installation will have new, client specific tables, in a client specific schema.
We wanted to have all of the _detail tables hidden. To choose what to expose. To rename some things here and there. To lift the foreign key relationships from foo_details to the exposed foo. To have all authorization handled by the application that already handles it. To allow subscriptions to root objects with as little overhead as possible. To add custom pub-sub channels that were also available for customers. To have a client installation include client specific tables (albeit with a bit of renaming to guarantee no conflicts between what the client has and anything we ever will have in our core product). And to make it easy to maintain it going forward.
3 of us independently looked at all the available tools. We independently came to the same conclusion. The two most mature products were Hasura and Postgraphile. Hasura on our database presented an interface that was nothing like what we wanted to show, and we didn't see how to customize to be what we wanted. Postgraphile did a better job out of the box, and we could see how to make it give us exactly what we wanted. (Yes, we had to do things like add pg_notify statements to our stored procedures, but it was straightforward.)
And yes, the language mattered. For example neither Hasura nor Postgraphile offers an out of the box integration with the random CMS we were dealing with. But none of us know Haskell, all of us know JavaScript, and Postgraphile is not hard to integrate with passport.js. And through that we can do anything that we want.
There is an old programming rule. "Only one person gets to be clever at a time." We were already dealing with a database schema with a lot of cleverness built in. Hasura has a lot of cleverness as well. You are right that Hasura didn't want to actually control* our database, but we broke its expectations pretty badly and would have to modify it pretty extensively to make it work like we wanted.
The primary complaints I hear from others about GraphQL are observability and the learning curve for devs who are new to it. I think these projects add a lot of value with tools like the GraphQL playground (similar to GraphiQL but better), middleware extensibility for observation/analytics, their documentation, and most importantly the starter/boilerplate projects.
IMO, the preferred option today is Prisma. They have a non-production-ready v2 that is available for testing. But even v1 is good for an enterprise product; and they're working on migration/codemod to get onto v2 when it's ready.
But the other big piece of the puzzle is deciding on a GraphQL client. It seems like most choose Apollo + Redux, but Relay is, without a doubt in my mind, the better library/framework for consuming GraphQL in the frontend. Facebook designed React, Relay, and GraphQL to work together really nicely. Relay takes some re-learning to think about frontend data dependencies and caching, but it's really well designed.
I think GraphQL on its own has value as a centralized contract between frontend and backend services, and is a nice query and mutation language; but without Relay I don't think you get the full benefits of all the hard work that goes into the GraphQL service design. And teams/organizations that end up with Apollo/Redux designs suffer from complexities around cache management that Relay does a better job of reducing.
The Prisma datamodel very closely mirrors the GraphQL schema. It has just a bare minimum variance to allow different data types (and maybe something else I'm forgetting). I think the generated GraphQL for the database client ends up being simpler and easier to debug; but that's just my feeling about it.
The Prisma database admin tool at `host:port/_admin` is nice; and compliments the GraphQL Playground really well. Prisma develops GraphQL Playground as an open-source project, inspired by GraphiQL which comes out-of-the-box with graphql-server.
RPC tightly couples frontend and backend. Decoupling is usually only needed for (very) large applications; while getting there you migrate from RPC to GraphQL.
I think if I was going to be deploying a real database (PostgreSQL), I'd want to do things with authorization and network configuration; at which point I'd be dealing with enough stuff around the user profile that I'd want my preferred query and mutation design (GraphQL + Relay).
If at any point you're going to be fetching data containing long lists, I'd also prefer to be working with GraphQL and Relay because the design is well thought-out for doing filtering, pagination, and caching.
Decoupling is good any time you want to allow different parts to change independently. Migrating architectures can take a significant amount of effort, but it just depends what you want to accomplish.
That said, if you prefer using Relay + GraphQL over writing SQL queries, then Wildcard (and RPC) may not be the right tool for you. Although I'd worry about the complexity of your stack. Unnecessary complex stacks tend to be an evil time sink in the long run. Simplicity is key.
RPC + PotgreSQL is fundamentally simpler than Relay + GraphQL + Hasura + PotgreSQL.
The thing is that you need GraphQL only when you need to expose your data to third parties.
GraphQL = generic API = thid-party devS.
For consuming your database from your own frontend, you don't need GraphQL and RPC is enough and simpler.
> Decoupling is good any time you want to allow different parts to change independently
With Wildcard(/RPC) you deploy frontend and backend at the same time but you develop both independently.
Migration is easy when you create a GraphQL API in parallel to your existing RPC API and progressively transition from your RPC API to your newly created GraphQL API. That said, chances are high that GraphQL will never be needed; only very large companies need GraphQL (the organization is so large that exposing an API to the whole organization is almost like exposing an API to the whole world). Basically devS of very large companies ~= third-party devS and you then need a generic API such as GraphQL.
(shameless plug)
Several months ago we switched to Postgraphile, and it solved the issues mentioned above. The plugin system allows us to implement the custom logic in a simple and performant way, whether it's a custom validation on a mutation or tweaking the GraphQL type system. And all the logic is centralized in one project. It's clean, fast and testable.
Another big advantage is that Postgraphile relies on Postgres RLS for permissions, which allows us to manage it using normal SQL migrations. In comparison, we had a lot of pain evolving an existing permission schema on Hasura.
Postgraphile can also automatically expose a Relay compliant schema, supporting Relay connections. It's not possible with Hasura.
Except for pure read-only GraphQL APIs, I strongly recommend looking into Postgraphile over Hasura.
Combine Hasura (automatic GraphQL on top of PostgreSQL) with React Admin (low code CRUD apps) and you can build an entire back office admin suite or form app (API endpoints and admin front end) in a matter of hours.
This adaptor connects react-admin with Hasura: https://github.com/Steams/ra-data-hasura-graphql
Here's a reference application I put together: https://github.com/cpursley/react-admin-low-code
Would really appreciate it! :)
The advantage is React Admin is back end agnostic and you can tap into the huge React ecosystem. And with Hasura you get automatic GraphQL endpoints (Django nor Rails Active Admin do this - you have to create models first vs just a schema with Hasura) which can be used for more than just your admin backend.
Hasura also ships with websocket support, something that Django has always struggled with.
The django admin interface is not usable by a frontend as an application API.
Django requires you to "meta-model" you have to write Python classes that map to your tables, this is usually duplicate work.
Django's ORM must support many databases, so it produces "least common denominator" SQL and is (stock) oblivious to Postgres' many enhanced data features, you are forced to use various community sourced extensions to get access to features that have been in postgres now for many years.
Django's security system is django only. You are forced to go through django for access control across your business. Eventually this abstraction leaks, and someone starts logging into the db from some other framework and now you have two problems.
This is my opinion and I'm sure I'll get downvoted for it, but Django, Rails, Node, all the Java frameworks, all the meta-modeling and NIH syndroming, are all utterly obsolete. Everything they do can be done in 99% SQL by a data scientist with the help of a competent DBA. "Web application programming" is going to go the way of the dodo bird and devs who don't start learning higher level skills like complex SQL, statistical modeling, linear algebra, and to either be a competent DBA or learn how to treat them fairly with be the first batch of programmers "automated out of a job" by tools like Hasura.
You don't have to duplicate any work because you don't actually have to write any raw SQL, since it all gets translated by Django. So yes, there's an extra layer of abstraction there, but no duplication on the developer's part.
> Django's ORM must support many databases, so it produces "least common denominator" SQL and is (stock) oblivious to Postgres' many enhanced data features, you are forced to use various community sourced extensions to get access to features that have been in postgres now for many years.
Practically every Django release adds support for more and more database-specific features out of the box, to the point where I don't remember the last time I had to use a third-party library to take advantage of a PostgreSQL feature. But even if you do, so what? It's no different than using a Postgres extension.
The HUGE advantage that ORMs like Django, Rails, etc have over writing raw SQL is their composability. Django provides lots of tools that make it VERY easy to reuse code relating to models and querysets, whereas SQL is notoriously difficult to keep DRY. And this issue gets significantly worse when you start to pull in data that lives outside of the DB.
On top of that, there is the more obvious issue that good DBAs are rare and expensive compared to Python/Ruby/whatever engineers.
> Django's security system is django only. You are forced to go through django for access control across your business. Eventually this abstraction leaks, and someone starts logging into the db from some other framework and now you have two problems.
I do completely agree with this, and I think it's Django's weakest point by far. But you can always forego the ORM's integrity/trigger features and add those at the database level in your migrations.
> This is my opinion and I'm sure I'll get downvoted for it, but Django, Rails, Node, all the Java frameworks, all the meta-modeling and NIH syndroming, are all utterly obsolete.
Hasura and related projects are really great, don't get me wrong, but this is outright FUD. There are pros and cons to both approaches, and to claim that one is "utterly obsolete" is nonsense. There are lots of situations in which turning the database into your API just doesn't make sense.
There is still some duplication of effort, for example when you change the model, yes django will create the migration script for you, but you always have to verify it and often change it especially when you're merging branches. And since the migrator only supports a subset of postgres' DDL abilities, even simple things like renaming objects, or applying advanced indexing techniques you often have to write hand sql migrations anyway, which require you knowing sql, so why not just do all in sql?
> Hasura and related projects are really great, don't get me wrong, but this is outright FUD. There are pros and cons to both approaches, and to claim that one is "utterly obsolete" is nonsense. There are lots of situations in which turning the database into your API just doesn't make sense.
It was a strong statement of an unpopular opinion, but FUD is a fundamentally dishonest statement, and I did clearly prefix my statement with "This is my opinion and I'm sure I'll get downvoted for it". As someone who knows my opinions well you know I honestly believe it. But that's ok I appreciate you keeping me on my toes when the coffee gets me in an agitated state!
That being said, I still do believe it. I do pick on Django pretty hard, but I feel the same way about many of the Python frameworks to a certain degree and the "web application framework" pattern in general. Django is just the one I have seen the most bloviated circumlocution of code to do simple tasks with, and often when I have run into problems with Django, it was usually Django's fault (ahem, autocommit) not the developers. It's a classic foot gun.
A recent example I have had to boggle at, a half dozen AppEngine microservices, cross calling each other with http RPC all autocommiting to 3 different postgres databases with less than 100k rows of data total. The microservices were entirely responsible for maintaining referential integrity entirely defeating the point of using postgres in the first place.
The whole thing could have been a set of simple functions, much of the heavy lifting could have been done with some simple triggers. But instead "microservices". That worked ok when there was only one instance of each service, but then when app engine scaled up it became a knot of race conditions.
Aside: I'm working on a GraphQL library for Python that I hope will fulfill these goals, but development on it has stalled due to lack of time. Hopefully I can pick it up again soon.
FUD may have been strong, but in general I detest when people decry entire categories of technology as being "wrong" or unfit in an absolute sense (or, conversely, tout a technology as a silver bullet), when in fact everything has its tradeoffs and there are good reasons to use almost anything. Understanding those tradeoffs is vastly more important than searching for the universal answer to everything.
PS: Hope you're doing well! :) Your contact info isn't on HN, but email me if you want to get coffee/lunch sometime!
E.g. https://github.com/reframejs/wildcard-api for JavaScript.
The neat thing about RPC is that you can tap into the full power of PostgreSQL "directly" from the frontend.
The thing has a bunch of complex business and authorization rules. Not to mention a bunch of per-client customization. There's also some neat handling around versioning and copy-on-write type behavior to provide a mix of immutability and space saving.
To me, this is CRUD because: most resources literally have 4 endpoints (create, index, update and delete). We write a ton of tests to cover all the cases. It's time consuming, even tedious, and it's boring / simple compared to the user facing stuff we do.
I've never touched GraphQL, so can that really save me months of work? Or would it save me about as much time as Rails would (which would be not a lot) ?
Its main effect is to move app logic query writing to the frontend, in something that's not SQL, which some folks seem to really like. But it's still got to get turned into whatever your data sources actually speak at some point, just like REST or anything else. If there's nothing magically doing that for you or if the magic turns out to suck, you'll be doing it manually.
[EDIT] to make it more clear, here are your possibilities:
1) a. GraphQL queries -> b. Queries for one or more kinds of datastore
2) a. REST requests -> b. Queries for one or more kinds of datastore
You shift choices about how to query kinda forward in 1, but that means you need a very general and flexible GraphQL query handler to make step 2 happen, and if that doesn't exist or is insufficient you have to write it. That is, obviously, more work than 2, in which 2b is where the choices you'd make in 1a happen, so that layer doesn't need to be as flexible.
TL;DR the apparent flexibility and responsibility-shifting of GraphQL isn't free and is in fact quite expensive (and, if I may, risky)... unless it is free because someone's already done the work, for your particular use case and stack.
Hasura aside, GraphQL will save your API consumers time more than anything else. Like the other comment/reply to this, you still have to build a GraphQL server.
[1] I'm twitter.com/tanmaigo or tanmaig@hasura.io
In contrast, tools like Hasura and Postgraphile can potentially save you time because they generate the GraphQL part for you. Then you only need to handle the authN/authZ parts – in theory, at least.
Posting here as it may be of interest to readers: l https://massiveinference.com
I love Django, but even its amazing ORM has limitations. I can't imagine what it's like to deal with something similar but on the frontend instead...
The thing I love most about GraphQL is that serves as the perfect contract layer between the front end and the backend. A very productive development method I've used is to have the front end and back end teams agree on the GraphQL types (often times having the front end folks actually write the types), quickly mock things out, then have the front end folks go implement the front end and the back end folks provide the real resolver implementations.
The things I love about this is that it really simplifies and hides the backend details from the front ends. With things like Hasura, you are directly exposing your DB schemas to the front end, essentially tightly coupling them together. That has always been a recipe for disaster whenever a project gets sufficient scale or complexity in my opinion.
Again, it was a long time ago when I dug into Hasura, but this whole concept of "Directly expose my DB schema as GraphQL" is the exact opposite of what I love about GraphQL in the first place.
Why not separating concerns instead of separating technologies? Tight coupling of UI with database but decoupling of e.g. admin UI/backend from end-user UI/backend.
I'm the author of a Node.js RPC implementation (https://github.com/reframejs/wildcard-api) and the idea is the exact opposite of what you are prescribing: highly coupled frontend business logic with database schema/queries. Makes things so much simpler, in my experience.
- it is made in typescript and can be integrated as a library directly in a JS project
- it is very easy to extend with plugins
- it is very easy to customize and run on an existing database
- it is « database first » in the sense that the schema is created based on the DB schema and some additional annotations
- it is really free open source software with a non-VC backed business model
- it is extremely performant
Do you have any other point to sustain this comment of yours?
> my conclusion is that PostGraphile is way ahead of all this
- Like Hasura, has ALL the features of Hasura
- BUT really FOSS with no VC funding, supported through Patreon by a super nice team.
- AND I have all the source, in the same language than the rest of my stack, the language that my developers know
- AND it does not require to run yet-another-microservice but is just part of my graphQL server
- AND it is extensible through plugins that blend seamlessly in the server (unlike Hasura where I see no sign of plugins, and I don't want to write plugins in Haskell)
- AND it supports native, super-fast Postgres Row-Level-Security instead of rolling their own!
That is very clearly compelling enough to support my conclusion, from my point of view.
Let me also mention that I have been burnt by another VC-funded GraphQL server company, namely Prisma, which left us stuck with an old, non-maintained buggy version which is near impossible to patch and build ourselves, while they work on their pie-in-the sky Prisma v2 which is totally the wrong direction in my opinion.
We jumped ship from prisma, considered hasura, but went for graphile and love it!
Unless I'm missing something, Hasura is FOSS too.
https://github.com/hasura/graphql-engine
True, Hasura does not have plugins (AFAIK) but you can extend it's funcitonality via webhooks and PG views.
As for authorization it may give them more flexibility to roll their own.
Anyway, thanks for bringing up PostGraphile. I'll check it out!
Both feel kind of limited by forcing you to encode a ton of logic in SQL which must be migrated vs a mongoid model you can just tweak and commit, but I guess I'm old school and what's old is new again.
Imagine a very simple scenario, you want to add some validation based on business requirements, in order to do that you have to have a server with custom endpoints or a custom graphql server (thus copy most of what hasura generates) to implement your own validation
The only situation in which I consider this a really good solution is in a CQRS system where the database attached to hasura is read only via graphql and the data is inserted by other services making it a typesafe single source of truth to read from
Here's an example for a regex for validating email from one of our community calls: https://youtu.be/-9jX21PKyk0?list=PLTRTpHrUcSB8Dp3hk5SiVNHNP...
For internal or prototypical use cases, that can be totally sufficient, however you‘re right that you‘ll eventually want good error messages, observability and much more other custom logic.
What I‘m still searching for is something that works like Hasura or PostgREST and then offers „upgrades“, first via configuration, later via custom code hooks.
That would be pretty awesome from a migration path perspective.
Both Hasura and Postgraphile also support schema stitching from what I know, so you should be able to extend it that way also (more complicated obviously)
Writes (mutations) are delegated to a REST endpoint, the GraphQL mutation response can be synchronously (blocking mutation) or asynchronously consumed (mutation + subscription).
Will give it a try, thanks
What I really want/need is custom logic that run IN the resolvers of already available query/mutations with the request as input and the possibility to either return an error or modify the payload before it hit the database
but I know is still in preview, will check it again when released
Consider Django. Your django app logs into the database typically as a user with elevated permission that is a superset of all permissions required by your users. Postgres has no idea that django is acting on behalf of many users, all it sees is this django super-like user. If an attacker roots your Django instance, they have the same privileges. If your PHB decides to "help" and log in with creds found in the source code, the damage could be catastrophic.
Products like Hasura, Postgraphile and PostgREST switch databse roles on the fly per-request. The user that these tools logs in as typically has almost no privileges. You must be the bearer of a valid JWT token to elevate privileges, and then you only get to the level of the user you stole the token from. There is NO super-like user.
I agree with your overall comment. Note that Hasura doesn't use the native row level security in Postgres. They implement the layer themselves. There are two reasons: 1) Hasura is older than the first release of Postgres that included the row level security feature. 2) Their implementation scales better when there are a lot of users subscribed to the same GQL Subscription. When using row level security, every user's query result looks different, so they need to create a database subscription / polling for each user GQL Subscription. Their implementation allows them to have a single PG subscription (well they mostly do polling), get all the data back, then strip down on the way out to the GQL subscribers.
the Graphene implementation for Django brings up a Relay GraphQL server so fast. The best part is that at compile time it ensures your GraphQL schema confirms to the Relay standard, enforcing correct naming. You really don't have to think about much.
The scope is smaller than GraphQL, but some of the interesting benefits - like smarter and more optimized requests - are available with PostgREST.
For example we currently are required to talk to some external auth services (depends on the customer) and fetch the users permissions based on that, (e.g. user can READ notes, and WRITE notes but not delete NOTES). At the time we had an extremely simple express middleware that handled this.
Also the entire idea that i need another GraphQL or rest server to do any sort of custom validation/custom actions made me do a double take and more or less killed any interest to me.
We ended up using NestJS with their GraphQL tooling and objection.js and never looked back. Ironically the adoption of the GraphQL version of our API compared to Rest is almost 0.
We're working on making it easy to integrate resource claims and rule engines that are external as well (make an IO call instead of embedding the rule in the SQL query itself). The good news is that it is possible to do at the Hasura layer because Hasura owns the RBAC so we'll get to it soon enough :)
Over the last few months, we've seen users flip from their custom GraphQL servers to using Hasura because of the reduction in code/maintenance that Hasura brings for their use-cases. Especially when you have a large number of tables. Being able to manage authorization rules at a "type" level instead of a "resolver" level also makes things convenient.
We've also started work on making it easy to integrate REST APIs for custom logic (esp writes) which also helps skip a bunch of GraphQL/authz boilerplate: https://blog.hasura.io/introducing-actions/
Actions look painful, i don't want to write and maintain microservices just to do simple actions. I just want to be able to write code and handle the hook around the function. Also from the link it only seems like actions occur AFTER something happens, i need the ability to run before changes are persisted.
The main reason for me was RBAC. Converting db-to-api is not that hard but providing access control almost always requires some form of middlewares. Hasura does RBAC very well.
Another feature that I haven't deployed but find useful is webhooks. You can trigger webhooks as your data changes.
I do need a server to handle object storage, email and cron so it's not a 100% there, but I can see the appeal of rapid APIs at low cost.
Also subscriptions are <3.
All the best to the Hasura team.
These roles can be assigned to a frontend session by generating signed JWTs.
With Postgres RBAC, you'd need something to lift the roles to be consumed by the frontend. With Hasura it works out of the box.
Also, I did consider using Postgraphile, but it was easier to get started with Hasura, so I went ahead with it. I don't have enough info to make a comparison.
I feel that products like Hasura and postgrest would be a lot more useful if there was a way for me to specify a list of data sources on one side and get a fully formed GraphQL or REST service on the other side rather than going "I know what you need better than you" route.
It requires you to learn more arcane technologies (postgres functions are a bit less beginner-friendly than, say, ruby on rails) but these are also great technologies to know.
My guess is that a production hasura/graphile/prisma app would end up having a large number of custom resolvers by the time it's seen a few years of heavy production development as well, and that the built-in gql queries would serve more as scaffolding for prototypes, but I've never made it that far myself.
I found all the answers in the docs.
A SQL Schema can carry a custom query, it's called a view.
A SQL Schema can carry a custom algorithm, it's called a function or a generated column.
You can always deactivate permissions on a table to not expose it, my bet is that your backoffice will need to though.
On top of that, Hasura supports custom resolvers (code driven endpoints).
Finally you can stitch 2 GraphQL schemas together. It doesn't have to be one size fits all. So even if only 50% of your app can fit in the model of Hasura, you can always mix and match. It's still 50% that will be up and running in minutes.
This is not feasible. I might not have enough access to create views. I might not have access to create functions. I cannot deactivate permissions if I only have a single access account and other systems use it already. You cannot assume that I have full control of the database or that I can easily make changes to the schema.
But this is not all. I am working on a web backend project on daily basis. I would love to offload some basic CRUD operations to something like postgrest or implement GraphQL with something like Hasura, but I need a way to a) define table and field name mappings b) define what tables are accessible b) define what columns are visible c) define what nested relationships are allowed d) define actions that need to happen on update/insert/delete operations (i.e. push a message into a queue every time a record is deleted from table T) If I could do all of this, I could implement about 50% of my web service and it would be useful.
Concerning the lack of sufficient privileges to create a view, you can always either ask for permissions, or create a second databse with FDW. Apparently reading your second paragraph you are allowed to create tables, so it sounds like you'll also have enough privileges to create views.
I don't understand your point on your second paragraph. You can do all of that in Hasura, it's in the first tutorial, but also the doc. Please note we are talking GraphQL so there is no CRUD. It is a query + mutation model. More flexible and powerful than CRUD.
Hasura internally has a metadata engine that does exactly this. You explicitly specify what tables/views/functions you want to expose and how you want to expose them. You can use Hasura authz to further constrain what data is accessed/returned while a query runs. In its default configuration when you start Hasura against your Postgres, Hasura exposes nothing.
Isn't the point of GraphQL to decouple your interface (who should not break) from your backend implementation details?
Either it is an internal service, only consumed by your own products, and then it's fine. Or you have an API gateway to control who and how your services are queried.
The API Gateway is your interface who should not break. Your services communicating with your database (through Prisma, Hasura, any ORM, ...) can and will break.
When you base your GraphQL schema on your database schema for your internal services, you get rid of one long and annoying step of putting glue everywhere. This is especially true in a microservice architecture, and even more in the corporate world where you are expected to produce code quickly.
You don't. Hasura (and Postgraphile and PostgREST) employ in-database modeling tools called views. Views provide the same modeling abstractions that ORMs provide.
https://www.postgresql.org/docs/12/sql-createview.html
A view is a canned query with a name, and when you get down to it, all an ORM is doing is producing, usually poorly, a query from a named abstraction. Same thing. So why have two pieces in two languages when you can have one?
> Isn't the point of GraphQL to decouple your interface (who should not break) from your backend implementation details?
Views provide the same or better decoupling. They database is aware of them, they are type checked, you can't even make a view that references an unknown column, for example.
Hasura is truly a marvelous piece of software when it comes to rapidly prototyping and getting things out into production. We discovered Hasura a couple years back at my previous company when it was still in beta and we were amazed with how easily we could automate most of our CRUD logic. I will definitely be using Hasura again when the time comes around.
On a more recent note, I currently have a client who's prototype was built with Hasura but one of their requirements was to migrate to AWS and use as many of the PaaS offerings as possible. We ended up using AppSync[1] and it is fairly impressive. I highly recommend anyone who is stuck in the AWS ecosystem to check it out. AppSync integrates with a lot of other AWS services (Cognito, S3) very easily and allows you to use Dynamo/Aurora/RDS/Elastic as data sources. On top of this, you can also use Lambda to implement resolvers that need more intense business logic, making the service incredibly powerful.
I think for us, the biggest issue so far has been figuring out some of the more involved Velocity templates as the documentation is fairly sparse and testing them can be a pain. Thankfully this project isn't too business logic heavy but due to time constraints, we ended up writing Lambdas for templates we could not figure out quickly.
(And a way that doesn't require writing rollbacks, which sometimes aren't even possible anyway).
Their migration tool is really nice; reminds me of Rails but better as you can write raw SQL.
https://github.com/hasura/graphql-engine/tree/master/scripts...
PostGrest has none of these problems, but/and no graphql. It’s where I landed.
Also, check out dbmate for agnostic rollback management. All it needs is a way to template the sql and I’ll be happier. Some folks using Postgrest use Alembic and SQL Alchemy to build/manage migrations—I’m not sure where I sit on that yet.
Feel free to check it out: https://github.com/sastraxi/great-bear
https://translate.google.com/#view=home&op=translate&sl=el&t...
The spelling "hasura" is in what we call "Greeklish", i.e. Greek in English (ASCII, really) characters. This was common in early 2000s, where utf-8 support was not everywhere (web, SMS, etc) and writing in Greek characters had a high chance that the recipient would receive mumbo-jumbo.
I feel like graphql would be much easier to adopt of it just sticked to rest conventions as much as possible. Like have the query language be pure JSON.
It should even be possible to design it so that you could make drop in replacements for most of existing rest APIs.
On the client side is the same, following any getting started guide can explain 90% of what you need to know in a single day
The subscriptions are particularly interesting to me, I've never seen anything else that makes web sockets so easy to implement. I'm very optimistic for their future.
Congrats to the folks at hasura for the raise, long live postgres and graphql.
[0]: https://registry.terraform.io/modules/Rayraegah/hasura/aws
One way to think about this is that with RPC you remove the whole API layer and directly write SQL queries instead, while permissions are defined programmatically on a case-by-case basis. This is much simpler than Hasura!
For Node.js there is https://github.com/reframejs/wildcard-api.
For other backends you can implement JSON endpoints (https://github.com/reframejs/wildcard-api/blob/master/docs/b...)
While scaling to a large company, you progressively migrate from RPC to GraphQL (with or without Hasura).
But I took a look at your RPC tool, and it adds a lot of boilerplate work. This RPC boilerplate is exactly why alternatives like Hasura, Prisma, and Postgraphile exist.
Also you can't add an RPC layer and magically call it simpler. If you add Postgraphile, Prisma, Hasura in front of the database, it is just as simple, just as much a layer on top of the database. Only in this case you're writing to a published open spec (GraphQL) so the client doesn't have to know if it's talking to a relational database, a Redis cache, a REST data server, an in-memory data model, or whatever.
Your tool on the other hand is just another vendor-specific ORM or manual query engine. If that works for you, great. It is not a good alternative or answer to what is being discussed here.
I agree, Hasura and Wildcard have different goals. Still, the merits of each tool can be talked and discussed about.
> you aren't writing any SQL queries. You are creating your database schema and then launching the respective apps. Obviously some customization will be necessary since almost no app are 100% CRUD.
I'm not against ORMs. On the contrary, I've always been (and still am) looking for an ORM that takes care of 90% of queries (basic CRUD queries) while preserving the full power of SQL for the 10% of queries that require more powerful queries. Most ORMs do that part wrong and make writing custom SQL queries complex. I really want such ORM and I even tinkered and implemented one for a hobby project.
Also I believe that an ORM to be a wonderful combo with Wildcard, such as Prisma. (Prisma is pretty much an ORM and can be used without GraphQL.) I would argue that Prisma + Wildcard to be superior to Prisma + GraphQL. (With the exception of when you need need third-party devS to access your data -- you then need a generic API with either REST or GraphQL.)
> But I took a look at your RPC tool, and it adds a lot of boilerplate work.
I couldn't disagree more; Wildcard is deliberately designed to abstract away as much boilerplate as possible. I'd be more than happy to see a concrete example that proves me wrong. My guess is that you won't prove such example because there virtually isn't such.
> This RPC boilerplate is exactly why alternatives like Hasura, Prisma, and Postgraphile exist.
That's a vague sentence and doesn't make any sense to me.
> it is just as simple, just as much a layer on top of the database.
Wildcard is only a couple of KLOCs while Hasura & co large and complex tools developed by teams and backend by big VC money.
You can read Wildcard's whole documentation in 10 minutes. Reading Hasura's entire documentation is much larger than Wildcard's.
It speaks volumes about how much simpler Wildcard is in comparison to Hasura.
It's weird to say that Hasura is as simple as Wildcard.
> the client doesn't have to know if it's talking to a relational database, a Redis cache, a REST data server, an in-memory data model, or whatever.
Such decoupling is mostly useful for very large projects. The vast majority of apps out there don't need such decoupling. Separation of concern is important, but based on concern not on technology.
> Your tool on the other hand is just another vendor-specific ORM or manual query engine.
It's weird to call an RPC implementation an "ORM" or "query engine". I'm not sure how an Software Engineer is able to mix up "RPC" with "ORM".
Honestly, your whole post is weird to me, I'm not sure what your motive is. You seem to try to put down an open source project that is being developed by someone in his free time and without any remuneration. That's disgusting and without taste. If you only have a lack of tact then I apologize for my words.
Just to be clear I do like many aspects of Hasura. The problem is that, 95% of the time, GraphQL is not being used in the right situations. GraphQL when used correctly is a lovely tool. (Basically GraphQL = generic API for third parties. If you don't need third parties to access your data then you don't need GraphQL.)
Irony is dead.
Do you see the code right here? ``` endpoints.createTodoItem = async function(text) { ... } ``` You've already missed the point of tools like Postgraphile et al when you propose tools like that in a discussion like this. You don't have to write endpoints or even GraphQL schemas at all. You literally just start the tool, passing in the database connection info, and start using it. That's it. That's all. That's what I meant by simple, not how many lines of code they required (which is not much of a benchmark). That's what I meant by apples and oranges. I'm sorry you saw that as an attack, but it's true. It is not just a matter of replacing GraphQL for RPC as you suggest. Or REST for RPC. Simplicity from the point of view of the user, not the server parsing code. Your server is effectively writing a data schema to be consumed by a client. These GraphQL tools write the schema for you.
No code at all (other than database setup) is required to get this working. Zero. https://www.graphile.org/postgraphile/usage-cli/
I hear you on the comment "Is your API meant to be used by yourself? Use Wildcard." However at that level, ANYTHING works. If you start with REST or GraphQL, you may not need it now, but if your project grows, you'll have to rewrite everything. Another minor nit: GraphQL does not require HTTP or even a network layer. GraphQL in and of itself is 100% transport-agnostic.
Sure you could auto-generate RPC endpoints from your database schema, but that requires a tool that does not yet exist, does it? And at that point, what advantage does it afford over GraphQL? It's not markedly more efficient. For that matter, if you wanted the most efficiency regarding RPC, why not use something like gRPC that uses protocol buffers for serialization? If that level of efficiency isn't necessary, then how can you criticize minimal protocol efficiency differences between RPC and GraphQL?
Then there's the issue of vendor lock-in. GraphQL is a spec, and a relatively simple on at that. Nothing more. Nothing less. For the most part different GraphQL backend implementations can be replaced with another vendor/implementation. REST is the same. Can the same be said of your RPC implementation? Could someone seamlessly replace it with another tool without changing any client code? Who are your competitors? (Not necessarily looking to outdo you, just occupying the same spec-level niche.)
As for VC funding, Hasura just got some. Prisma has some. Postgraphile is a one-couple shop with a simple Patreon. The REST libraries don't have VC funding to my knowledge, so that comment from you was largely unwarranted and frankly rude. But more to the point, lack of funding or a development team is not an effective point. What happens to the organization using your software if you get hit by a bus? Why should they take on that risk? Sure they can take over your code since it's open source, but if they wanted to go down that road, why wouldn't they just write their own code anyway? I'm not saying you have to be a major multinational corporation, but single points of failure are not selling points to most folks whether those single points of failure be technical or social.
Lack of redundancy is a hazard. Lack of choice is a hazard. I for one am glad so many healthy competitors exist in the auto-conversion of relational databases to GraphQL.
All the best of luck to you in your RPC endeavors. I'm sorry for being harsh, but you jumped into multiple threads promoting Wildcard without in my opinion understanding what you were comparing against. I hope you find an appropriate audience and user base for it. I fear however that this isn't it for the reasons I enumerated.
I'm a minimalist and as such I have a problem with complex solutions to simple problems. That's my whole point.
My dream ORM is a an ORM that is designed with a) an obsession on simplicty, b) simple ORM CRUD queries that cover 95% of the data mutation/retrival needs, c) allows you to write "native" (no)SQL queries directly for the 5% cases when you need more complex queries, and d) automatically takes care of migration for 90% of the cases.
The ORM should be trivial to understand, the documentation super small, and the ORM should get entirely out of your way if you want to use your database directly without the ORM. Most ORMs out there (if not all) get these things wrong.
Hasura, Prisma & other auto-generated GraphQL tools are essentially ORMs. Unfortunately, they also get the above listed things wrong. I like that they auto-generate a GraphQL schema, that's neat. That's not my problem. My problem is that they are tightly coupled with GraphQL. That's nonsense. Because (and Wildcard is a living proof of this) you don't need GraphQL for the vast majority of apps out there. People need to understand that GaphQL = generic API = third-party devS. You don't need to expose your data to third parties? You don't need GraphQL. Period. (I hear people arguing about decoupling frontend and backend by using a generic API but that's an old and out-dated idiom, which is another topic I'd be happy to elaborate if you want.)
A simple ORM with a plugin that auto-generates a GraphQL schema? Hell yeah that's awesome. You'd then use the GraphQL plugin only when you need to expose your data to third parties. That's cool.
You don't need to expose your data to third parties? Use an ORM with RPC.
RPC is fundamentally simpler than GraphQL. Why on earth should I use something inherently more complex if I can use something so much simpler?
For example, have a look at how permissions work with Hasura and compare this to Wildcard. The difference is worlds appart in simplicty.
With Wildcard, permissions are written in code:
// Node.js server
endpoints.deletePost = async function(){
// Only admins are allowed to remove a post
if( !user.isAdmin ) return;
// ...
};
This means that you don't have to understand anything to do permissions -- simply write if statements, just like you are used to while programming other sutff.With Hasura, you have to use Hasura's custom system of role-based permissions. What I find most annoying about these is that they are not defined in code. With Wildcard all permissions are written in the code - I can simply read them while reading queries.
I hear your arguments saying that Wildcard is new and I understand that you don't want to adopt something that is the "bleeding-edge". (From my perspective; from your perspective, experimental ;-).)
I agree that my way of promoting Wildcard on the whole Hasura thread was less than ideal, I'll improve.
Let's look at a GraphQL call in terms of simplicity.
await fetch({
method: 'POST',
url: 'http://server/',
body: `mutation {
deletePost(id: '542543') {
id
}
}`
});
That's it for a client call, and I know from the query that it'll return the id of the post (if any) that was deleted.Using Postgraphile as an example, nothing to do on the GraphQL server side beyond starting it up. In your database:
CREATE TABLE post (
...
);
REVOKE ALL ON post FROM public;
GRANT SELECT INSERT UPDATE ON post TO public;
GRANT DELETE ON post TO app_admin;
Done. The issue with your approach is that different sections of code may invoke SQL that deletes data. Once a data model lives long enough, edge cases show up. By having the security model live with the data itself, you never have to worry about these edge cases. Set theory for the win! Security bubbles up from the data layer, through the app layer, to the client layer. Also means that if you have two apps talking to the same database, you are no longer required to keep those security restrictions in sync. Got one app in PHP with another in Ruby? No problem. Data security is still intact. Forgot to restrict deletes? Fix the data layer, and the security fix bubbles up. No worrying about all of the possible places that might be affected by this.Data security at the app level is arguably the wrong level to be implementing it.
Now you may decry the complexity of a fully-formed solution, but honestly Postgraphile meets your requirements quite well. GraphQL really isn't complex on its basic level.
query {
post(id: 13245) {
id
subject
body
author {
id
name
email
}
}
}
Boom. That's the JSON that comes back—follows the structure of the query. Self-documenting. The generated CRUD endpoints cover 95% of needs. Native queries written with the database itself and exposed as functions. Migrations should be handled as either idempotent SQL DDL or repeatable sequence of files at the database level, not the app layer.Performance-wise, I strongly doubt you'll be faster/more scalable that Postgraphile out of the box. And just because the browser isn't calling the endpoint doesn't mean that GraphQL or REST are useless. Far from it. It's absolutely not just for publicly accessible APIs. That is a false assumption on your part.
GraphQL really isn't as heavyweight as you seem to presume it is. It's just a spec. How someone implements that spec is what makes the difference. As far as request/response sequence, GraphQL is quite cheap computationally. Well documented. Only as complex as the queries you want to make. Hierarchy-aware.
You might as well argue that HTTP is too complex and inefficient; that raw socket calls are better. Why not set up an exokernel?
The reason most of us don't is that it violates the 80/20 rule. Premature optimization and all that. If 99% of the time is spent in the database doing queries and only 1% in your app, fixating on the "efficiency" or perceived "simplicity" of that 1% is a fool's errand.
This looks really cool and an improvement on Prisma! I particularly like the much less bloated schema experience (and the builder) along with the easy addition of actions. We've been working on something similar but it's great to see improvements in the UX of the space.
Hasura is working to simplify that layer, but developers aren't cheap and I'd imagine the work isn't terribly fun. A lot of existing web frameworks have sprung up out of consultancies to support that development cost. Raising capital is just another funding strategy.
This is what I'm struggling with when it comes to weighing the pros and cons of GraphQL. I like the SQL model, ie pushing selects and joins and such to the DB, so why not from client to host too? But when you still need to enforce access restriction and such per user per action, how much time would it save me, really?
Seems great for internal apis or prototyping though.
If you accept that you don't want your web client talking directly to the database, then you need something that will interface with the database. That problem has been around for a while with many different solutions: SOAP, ReST, PouchDB/CouchDB, interface with various cloud services, something completely custom, and many others. GraphQL is just one of the latest solutions to that problem and with it, brings some advantages around flexibility in the API requests and responses. It also makes it easy to stitch together multiple GraphQL APIs. So, by being standardized* you don't need to develop the client code yourself and you gain the ability to pull together APIs from multiple sources to present as a single end-point. The most popular clients also provide caching mechanisms so you don't have to keep whacking the back-end for the same data repeatedly. There's also graphiql [1], which gives you a really nice way to query or modify your data on any GraphQL API, which I've found to be very helpful when learning new APIs.
So far, I've found GraphQL most useful for single page applications where the back-end really doesn't have to do much more than handle DB interactions. If you already have an application up and running with little churn in the API, adopting GraphQL probably wouldn't gain you much. In a greenfield application, I was able to use Hasura to replace a simple Rails CRUD application and that was handy. Hasura also takes care of JWT handling, so I could do my auth with Auth0 and not handle that in Rails either. I think GraphQL solves an interesting part of the serverless puzzle.
Don't get me wrong, GraphQL can be downright frustrating at times. Or at least the popular implementations of it can be. We use Relay at work and while it solves a lot of problems, it introduces many of its own that have cost me hours of frustration. I tried using AWS Amplify on a side project, and having to write new AppSync resolvers with Velocity templates is just not pretty. It really took using Hasura for me to finally be sold on what the GraphQL promise could be (side note: Hasura doesn't support the Relay protocol, so if that's important to you, you'll need to find a different tool).
* -- Standardized is a loose term. There is a GraphQL spec, but it leaves a lot available to implementation details. So, then there are other specs, such as Relay, built on top of that. Or de facto standards based on what the popular clients provide.
It's a big enough problem space I think and it has lot of scope for innovation. Enterprise Integration is also quite a big market, so there is definitely an opportunity to create a profitable company there.
Hasura provides an interface to a database(/s) engine. GraphQL was supposed to solve the interface problem but it looks like it has created a lot of accidental complexity to tackle.
Having used it for a number of years now, I still don't know why people recommend it beyond other people recommending it. Out of the box, it comes with no batteries included. Which explains the cottage industry that popped up to support it (Apollo, Hasura, etc.). Simply making GraphQL as efficient as bog-standard REST without involving the use of half a dozen 3rd party libraries is a fool's errand.
Silicon Valley suffers great amnesia and NIH. We've had RPC forever now. XML RPC, SOAP, thousands of others that don't deserve mention. There is a reason people moved from SOAP to REST: you didn't need that complexity. (On a side note, it makes me incredibly depressed to be in this industry knowing how much time and effort died trying to make XML a thing. When was the last time you heard "XML" on Hacker News? Probably been awhile. Maybe 5-10 years now. As a piece of news that is, and not some random comment from an asshole like me.)
Requesting arbitrary pieces of data on the client side (GraphQL's seemingly raison d'etre) is quite easy with REST. So easy that it makes me curious how much brain damage the industry has to think otherwise. Creating new endpoints even? Not a big deal. Not nearly as big of a deal as writing the mountains of boilerplate to get a new GraphQL query up and running. And considering we're talking about GraphQL, it's most likely going to be the same team members working on both sides. Why would that not be the case for REST as well? The mind boggles. All the arguments against REST that GraphQL camp makes are disingenuous at best.
What library are you using to generate the types?
This is the thing Hasura (and Postgraphile) is trying to make go away. From my limited experience with Hasura, it works pretty well.
I used to roll all of this stuff from Redux, with actions, reducers, the whole 9 yards. Apollo let me gut all of that-- since I was only using Redux to store data retrieved over the network. Now I'm not hear to preach Apollo specifically, but it's the only client I've worked with, and I can achieve higher productivity with it than working a lower level.
The advantage of this over a traditional ORM is that by having the entire query up front it can be smarter about how it does the translation.
Regarding REST, this is very very different. With REST, you map a single "query," the REST endpoint, to an SQL statement (ideally one). But if you want some other query, you're out of luck. Either you make a new REST endpoint, or you manually call several endpoints and compose the data.
There are some dangers to the GraphQL to SQL approach, namely it's harder to guarantee performance when the client can execute arbitrary queries.
Now, GraphQL by itself, I agree it doesn't solve the hardest problems: getting the data for the query and doing it security. But something like Hasura does address those points and I do think it is an advancement over previous technologies.
We covered a bunch of them here:
https://hasura.io/blog/fluent-graphql-clients-how-to-write-q...
https://www.moesif.com/blog/graphql/technical/Ways-To-Add-Gr...