Just another little shout out for Hasura here. It’s a really lovely system to use and the team behind it are awesome to deal with. Super friendly and helpful.
We evaluated a lot of stuff recently before settling on Hasura. Prisma, aws appsync, postgraphile, roll our own socketio backend etc. I had a few hesitations about Hasura. In particular I was hoping to lean on Postgres RLS for the authorisation, and to be able to customise the graphql endpoints a bit more. After hearing the rational from the guys about how their system is better than RLS and seeing the patterns they have for implementing the logic I’m really happy we made the leap.
We’re still in early days, but it’s been really solid and a real pleasure to use.
(No affiliation, but happily paying for their support licence)
Out of curiosity, what is the rationalle for abandoning RLS?
In a previous project, I used Postgraphile and enjoyed it. Sure, RLS and PLPGSQL were a bit awkward, but I knew they were well-tested and had lots of eyes on them, so I felt comfortable that if an RLS policy blocked access to a row, then that particular role wasn't getting access. I also enjoyed working with a text-based format that more clearly fit within my other workflows of, well, working with other text-based formats. :)
Another part of it is that I'm blind, and Hasura seems to make doing things outside of its web interface somewhat painful. Sure I can write a YAML migration by hand, but the YAML migration format seems more machine-friendly than user-friendly. Yesterday I needed to create a function, and the SQL web interface wasn't showing me the line number on which my function had an error. Ultimately I dropped to the psql command line, cut-and-pasted the function in manually, and right away got back the line number and fixed the issue.
Please don't get me wrong. I'm not trying to hate on Hasura. But the fact that I can't just drop to a non-YAML text-based format and throw down a few checks to secure my tables has been an endless source of frustration for me. So if there is a non-NIH reason for abandoning RLS in favor of a separate security system, then maybe knowing that might help me be a bit less annoyed. :)
Coming back to RLS, doing what we’re doing to fetch multiple results for different clients is not easy. Connection variable vs being in the same sql statement essentially.
As a blind person who works more productively in a text editor than a web interface[0], here are a few things that might help:
* Give me the ability to enter JSON directly in the permissions screen. I'm sure the query-builder is visually nice, but I can accessibly edit JSON strings better than you can accessibly visually render them, so let me just give you a string and have your interface validate it. Maybe just parse it, then transpose the values directly onto the form inputs in the visual interface.
* Give me a command to validate YAML migrations without applying them. This could even be a --dry-run flag to `hasura migrate` telling me what SQL would run and the JSON for my new/changed permissions.
* Some basic documentation on hand-coding migrations would help. I can sort of reverse-engineer them by pouring over the file formats, but the time taken to work more slowly in the web interface hasn't quite inspired me to take more time learning the undocumented format. :)
I'll see about filing these as issues soon if I can remember to do so. :) Either way, thanks for a cool product! Even if it frustrates me to use, tools like Hasura really hit a pain point for me in building apps.
0. Obviously that isn't universally applicable, but it is easier for me to solve logic problems than "why is my CSS all weird?" problems. Tools like Postgraphile and Hasura make it possible to test more of an app's functionality by writing just SQL rather than lining up my ORM with my language with my SQL schema. I guess just as Node supposedly reduces context-switching by placing more logic in a single language for front-end developers, tools like Hasura and Postgraphile let backend developers focus mostly on SQL when building out the app logic. And while I can't make something look good, damn can I think through how it should work and how someone might break it. :)
To be totally honest, I haven’t implemented anything using RLS, it just seemed the way to go since it’s native Postgres. The Hasura team gave me the same explanation as they give in this article - when you use RLS, you have to rerun every query for every client to get your results. By doing it in the application layer, you can run a single query instead.
In terms of the setup and migrations, I also have the same reservation about it being harder to do with text. So far I’ve left it to one of the other guys to implement so it hasn’t been painful for me, yet!
Edit to add: I believe they built their version of RLS before Postgres had it. So it was more a case of Not Invented Yet
I can't speak for the author, but having used RLS for authentication I would not recommend it. It complicates nearly every EXPLAIN plain, and it can cause performance headaches in even the simplest of queries.
We had to mark many internal functions as LEAKPROOF in order to get them to perform. It was not possible to move our database into RDS, so in the end we had to abandon the RLS authentication layer.
Thanks for this. Lots of developers fall into the trap of discarding concepts because they aren't Facebook/Google scale solutions. The app on which I used Postgraphile/RLS was likely to have only a handful of users, so I thought more about solving the problem effectively than about whether the solution would scale, so RLS seemed like an airtight system. Knowing that it kills performance puts things into perspective. It at least suggests which tool might be best for which job. :)
I suspect many of these concerns were with PostgreSQL 9.5 and 9.6 where RLS did indeed have many performance issues. PG 10 fixed a large number of these issues, and PG11 even more. I would recommend re-evaluating RLS performance on these latest PostgreSQL versions.
In Hasura’s use case it’s a little different. They’re working on the assumption that you have loads of identical queries that you want to run that differ only in the session variables (and hence the rows they see). Because they’re outside Postgres, they can collate it all and execute a single query for multiple users. Within Postgres you don’t have that luxury. It’s a trade off, but not using RLS suits some use cases better.
Oh good, glad RLS performance got a boost. Unfortunately my Postgraphile implementation for that project was replaced with Drupal, but I'm glad RLS performance is less of a concern under version 10 and up.
I'm yet to observe high perf hits on account my RLS impl. I captured data at some point for a 1M record domain with a couple thru tables, and query perf with and without RLS was indiscernible. Perhaps your check clauses we're expensive? I made sure to keep them as light as possible.
Hasura sure looks interesting, but two things make e hesitant:
1. The overly complicated schema it generates. For example, given an integer id, one can (and must) use various operators to query that id, e.g. `user(id: { _eq(1) })` rather than just `user(id: 1)`, where other operators are `_gt`, `_lt`, etc. To make this possible, hasura defines a comparison object, which results in a very long schema. However, often the only comparison that makes sense is equality, e.g. for IDs, so this should be optional.
2. More importantly, using Hasura establishes coupling between the DB and the GraphQL schemas. What if at a later stage one decides to remove information from the DB and move it to an external source? GraphQL was designed to hide such implementation details. With Hasura this is no longer possible.
And anyway, if the database schema changes, unless for some reason the turnover is very fast, you can still manually offer views for clients that require the legacy schema.
Not entirely but it crosses over. Appsync (from what I could tell) has a hacked version of Apollo for the front end and then it’s a configuration based system to provide graphql on top of dynamodb (someone can correct me in all of the above). But if you think of the backend of appsync as being a graphql engine with subscriptions and and a permissions system then there are a lot of similarities.
We evaluated a lot of stuff recently before settling on Hasura. Prisma, aws appsync, postgraphile, roll our own socketio backend etc. I had a few hesitations about Hasura. In particular I was hoping to lean on Postgres RLS for the authorisation, and to be able to customise the graphql endpoints a bit more. After hearing the rational from the guys about how their system is better than RLS and seeing the patterns they have for implementing the logic I’m really happy we made the leap.
We’re still in early days, but it’s been really solid and a real pleasure to use.
(No affiliation, but happily paying for their support licence)