[HN Gopher] GraphJin - GraphQL to SQL Compiler
       ___________________________________________________________________
        
       GraphJin - GraphQL to SQL Compiler
        
       Author : nikolay
       Score  : 63 points
       Date   : 2022-05-28 15:45 UTC (4 days ago)
        
 (HTM) web link (graphjin.com)
 (TXT) w3m dump (graphjin.com)
        
       | nsxwolf wrote:
       | I want to say something nice about this... but unless your entire
       | enterprise is a pure CRUD app with just a SQL database I don't
       | see how this is useful. Complex application backends pull data
       | from multiple sources - SQL and NoSQL databases, REST and SOAP
       | endpoints, message queues, service buses - and perform all sorts
       | of transactions and data transformations.
       | 
       | One of the strengths of GraphQL is you can transform data from
       | multiple sources into a common model the UI can use. If your
       | whole backend is a single SQL database schema GraphQL doesn't
       | seem to add a whole lot of value there. I'd rather have a code
       | generator that builds a simple Go microservice and use protobuf
       | JS in my front end.
        
       | pech0rin wrote:
       | Maybe this is a dumb observation but at this point whats the
       | point of even having a backend or graphql (except for maybe
       | authentication). If you are mapping the graphql to sql why not
       | just send direct sql commands. If you arent adding anything extra
       | whats the point of even using it. Just query SQL from frontend
        
         | theogravity wrote:
         | Because sometimes writing the equiv SQL can be a pain in the
         | ass. Pagination is such an example. PostGraphile does a good
         | job of it that I don't need to reason about it.
        
         | FrancoisBosun wrote:
         | This is called PostgREST: https://postgrest.org/. Never used it
         | in production, but PostgREST leverages multiple PostgreSQL
         | features: row-based security, schemas, authorizations, etc. I
         | quite like PostgREST, and I'd use it for internal stuff.
        
           | spoiler wrote:
           | We used PostgREST in a project at my previous company, and
           | it's the most horrendous thing imaginable. The project is a
           | meme in the company and nobody wants to work on it, including
           | its author (who decided to switch teams becaus of how much he
           | hated it).
           | 
           | I don't know if this was because of PostgREST or because all
           | the logic was encoded in grotesque looking SQL that nobody
           | understood (and changing some things requires dropping and
           | readding things).
           | 
           | It is an extremely cool project, don't get me wrong, but it's
           | one of those things that's "I know this already and I'll use
           | it for a weekend/poc project to not deal with writing a
           | backend" and not for something important. And again, I don't
           | know if this was just poor usage or something that manifests
           | itself in every project that relies on it. Also the DSL is
           | very much it's own thing, so migrating away from it is
           | painful, especially if you inherited the project and don't
           | want to read the document. But again, sample size is 1, so
           | it's anecdotal.
        
             | nick__m wrote:
             | I tried PostgREST for a small internal and it was a decent
             | experience. I followed the following rules:
             | 
             | 1- Don't expose your real database but expose a database
             | consisting of view on your real database so you can
             | refactor.
             | 
             | 2- Wrap your bussines logic in stored proc to keep your sql
             | readable
             | 
             | 3- Use jwt for authentication
             | 
             | That said, I would not recommend it for a large scale
             | application. I consider it, maybe wrongly, as the MSAccess
             | of the backend.
        
         | ricardobeat wrote:
         | GraphQL _is the extra_. It 's usually a lot easier to reason
         | about a graphQL query and the necessary data for a frontend
         | component, than to write a one-off SQL query for the same
         | purpose.
        
         | mdaniel wrote:
         | There are existing frontend tools that can compose GraphQL but
         | only string builders can compose SQL, AFAIK; it also seems to
         | act as a "paper over the underlying database specifics" by
         | using what seems to be MongoDB-esque criteria:
         | https://github.com/dosco/graphjin/wiki/Guide-to-GraphQL#othe...
         | meaning the consumer need not know the postgres-vs-mysql-isms
         | _(in theory, of course)_
         | 
         | Also, don't overlook the whiz-bang of the GraphQL introspection
         | tooling -- it's super handy for just kicking the tires on
         | something in ways that "dump the SQL schema to the browser"
         | likely wouldn't do
         | 
         | The related pg_graphql posted a while back
         | (https://news.ycombinator.com/item?id=29430720) actually
         | mentions GraphJin positively, and talks about a bunch of
         | competing implementations, although it's not one-to-one with
         | GraphJin because it seems to support mysql whereas pg_graphql
         | is of course a PG extension
        
           | cyanydeez wrote:
           | The iql tool is pretty amazing for coding up a query and
           | intro.
        
         | siva7 wrote:
         | oh boy we got to the point were we're wondering why we need a
         | ,,backend" anymore
        
         | nawgz wrote:
         | In my opinion GraphQL is operating on an entirely different
         | level to SQL in one meaningful way: manipulating structured
         | data
         | 
         | Manipulating rows in SQL is easy but doing nested joins and
         | trying to represent one-to-many relationships correctly in the
         | response is non trivial. I would say you have to be good at SQL
         | to leverage the DB to make structured data, returning tables
         | and rows is entry level.
         | 
         | In GraphQL on the other hand, it's seamless / entry-level to
         | query for nested data and represent it really semantically,
         | which is very appealing when doing presentational work (read:
         | UIs, I suppose).
         | 
         | Therefore, the purpose of constructs like this is to allow
         | those working on the presentational layer to be able to
         | construct queries for semantic, structured data themselves with
         | no requirement for SQL / backend expertise. This is a pretty
         | meaningful improvement to unblocking development for both sides
         | of the stack, in my opinion, and is why I apply Hasura
         | everywhere I can.
        
         | _query wrote:
         | This is basically the idea behind [Thin
         | Backend](https://thin.dev/). Instead of exposing raw SQL
         | strings we have a few high level functions to compose queries
         | in a nice way and to do all kind of CRUD operations. These
         | functions map 1:1 to SQL.
         | 
         | We use a WebSocket connection to keep all queries fast. Auth is
         | solved with row level security.
         | 
         | It's even in the name: The backend layer is just a "thin" layer
         | over the database. Most of the business logic is then
         | implemented in a "rich" client/frontend.
        
         | fswd wrote:
        
       | theogravity wrote:
       | Wonder how this compares with PostGraphile which I think does the
       | same thing and is pretty well-established:
       | 
       | https://www.graphile.org/postgraphile/
        
         | mdaniel wrote:
         | For one thing, GraphJin alleges to support MySQL and
         | YugabyteDB: https://github.com/dosco/graphjin#features
        
       | dfee wrote:
       | The most curious part of these tools (for me) is how they handle
       | cursor pagination.
       | 
       | Unfortunately, there are two closed out issues, seemingly with no
       | resolution, that seem to indicate cursor-based pagination doesn't
       | work (with Relay) and perhaps correctly (at all).
       | 
       | [0] https://github.com/dosco/graphjin/issues/44
       | 
       | [1] https://github.com/dosco/graphjin/issues/47
        
         | b-lee wrote:
         | Thank you. Any project that closes a real issue without solving
         | it is a joke to me.
        
       | mxstbr wrote:
       | Since founding GraphCDN, I've been surprised by how many
       | customers we see using Hasura. I was aware of Hasura beforehand,
       | but sort of wrote them off after seeing the fates of GraphCool
       | (pivoted to Prisma) and Scaphold (acq. Amazon).
       | 
       | Apparently, there's strong demand in the market for quicker ways
       | to create GraphQL APIs (see Graphile and now Graphjin), so I'm
       | excited to see more innovation in this space!
        
       | simonw wrote:
       | I built something similar to this for SQLite, as Datasette
       | plugin: https://datasette.io/plugins/datasette-graphql
       | 
       | You can try a demo here: https://datasette-graphql-
       | demo.datasette.io/graphql?query=%0...
        
       | turtlebits wrote:
       | "automagical GraphQL to SQL compiler" makes no sense. Is this
       | just another Hasura? Is it a compiler or a service?
        
       | _query wrote:
       | If you're looking for something like GraphJin, PostGraphile or
       | Hasura but with less boilerplate and complexity, more end-to-end
       | typesafe approach and optimistic updates, check out Thin Backend
       | https://thin.dev/ (https://github.com/digitallyinduced/thin-
       | backend)
       | 
       | Thin Backend takes a bit more of a higher level approach to
       | database operations than services like GraphJin, but solves
       | fundamentally the same problem. Doing things in a more structured
       | way also allows us to do things like optimistic updates by
       | default that require manual work with GraphQL tools.
       | 
       | To see some code examples, here's a small example project done
       | with thin-backend: https://github.com/digitallyinduced/thin-
       | backend-todo-app It's running on Vercel here: https://thin-
       | backend-todo-app.vercel.app/
       | 
       | If you're interested in how building a small demo app with Thin
       | looks like, check this video https://youtu.be/-jj19fpkd2c
        
         | MarkMarine wrote:
         | > less boilerplate and complexity
         | 
         | Kind of lame to pitch this in the comments on GraphJin. Make
         | your own post and try to get on the front page on your own
         | merits without bagging on this.
        
           | verdverm wrote:
           | I tend to disagree. A lot of discovery happens on HN.
           | 
           | Many posts will have alternatives posted in the comments.
           | Often the creator is the best to provide links and describe
           | the differences.
           | 
           | My alternative is a generalized DSL to code framework powered
           | by CUE. You can write directly in the output and later regen
           | because it uses diff3. Generate all the things in any
           | languages!
           | 
           | https://docs.hofstadter.io
        
           | _query wrote:
           | We have a couple users recently that are switching from
           | different GraphQL services, so I expect this to be relevant
           | for people checking out GraphJin :)
           | 
           | Thin was on the Frontpage of HN around a month ago:
           | https://news.ycombinator.com/item?id=31164799
        
       | justsomeuser wrote:
       | > _After working on several products through my career I found
       | that we spend way too much time on building API backends. Most
       | APIs also need constant updating, and this costs time and money._
       | 
       | > _It 's always the same thing, figure out what the UI needs then
       | build an endpoint for it. Most API code involves struggling with
       | an ORM to query a database and mangle the data into a shape that
       | the UI expects to see._
       | 
       | Most business API's have business specific per user read/write
       | access roles.
       | 
       | I am starting to think that a better solution to GraphQL and
       | other DSL's is to:
       | 
       | - A. Make the iteration speed of adding a new plain HTTP endpoint
       | very fast.
       | 
       | - B. Use a typed language, and some kind of macro to extract the
       | types into an Open API spec.
       | 
       | This way everything is just a regular function in your general
       | language:
       | 
       | - http_handler(request) -> response
       | 
       | - user_has_access(user, resource) -> bool)
       | 
       | etc.
       | 
       | Regular functions have no external dependencies, are easy to
       | understand, edit and stand the test of time better than DSL's.
       | 
       | If GQL does what you need out of the box, it seems a win. But I
       | would assume some endpoints need to fall back on the above
       | approach anyway giving you a mixture of GQL-generated and hand-
       | written handlers.
        
         | coredog64 wrote:
         | This is where something like OPA shines. Given a context, you
         | can make an up-or-down decision as to whether or not the
         | request is allowed. Then your not having to wedge security into
         | your ORM reshape code.
        
         | eandre wrote:
         | I've been building [1] for the past few years and it's pretty
         | close to what you're describing (and also does much more).
         | 
         | [1] https://encore.dev
        
         | klysm wrote:
         | I think tRPC.io works well for this, but haven't used it for
         | anything big. Curious what other folks think of it.
        
         | astockwell wrote:
         | Having used APIs from SOAP to REST to GraphQL and back, I would
         | agree. It got to the point in a recent project (written in Go)
         | where just slapping another endpoint on, even with fairly
         | particular nesting depth, was a 5 minute ordeal. That contrasts
         | in my mind against another recent project using interpolated
         | GraphQL which has been a struggle on almost every front:
         | struggle to CRUD data, struggle to fetch certain corner cases,
         | struggle with the performance/mem usage of the autogenerated
         | graphql -> sql translation, struggle to bolt on custom graphql
         | handlers for things not mapping neatly to models, struggle to
         | debug/test, on and on. Just write a goddamn JSON handler.
        
         | cyanydeez wrote:
         | Postgraphile allows for user roles,etv
        
         | strbean wrote:
         | Sounds close to FastAPI[1]. Anyone know of equivalent / better
         | frameworks in other languages?
         | 
         | [1]: https://fastapi.tiangolo.com/
        
           | martypitt wrote:
           | We build Taxi (https://taxilang.org), which is the type
           | system for APIs, and then Vyne (https://vyne.co) which uses
           | that types to automate all the plumbing.
           | 
           | It's pretty close to what's being described here, and removes
           | the boilerplate in API orchestration.
        
       | melony wrote:
       | Main question, how do you deal with authorization? PostgreSQL Row
       | Level Auth is horrible to use when you scale up compared to
       | implementing auth on the app level. Both Supabase and Hasura
       | suffer from this problem. The moment your data auth needs become
       | slightly complex, you end up with a mess of calling out to
       | external functions and ad-hoc SQL functions in the database.
        
         | ccakes wrote:
         | > ad-hoc SQL functions in the database
         | 
         | If you use tools like Sqitch, Metagration or any other suitable
         | migration management system then functions in your database
         | stop being scary.
         | 
         | Sqitch: https://sqitch.org/ Metagration:
         | https://github.com/michelp/metagration
        
         | dragonwriter wrote:
         | > PostgreSQL Row Level Auth is horrible to use when you scale
         | up compared to implementing auth on the app level.
         | 
         | In what way?
        
           | melony wrote:
           | When you have RBAC based on multiple different conditions,
           | e.g. "does user have XYZ?" you will have to architect your
           | entire app around putting these claims into JWT so the
           | GraphQL engine can properly map those onto RLS. In a
           | traditional app auth is on the app level and defined in code,
           | not a mix of code, SQL, JWT claims and Hasura/Supabase
           | configs.
        
             | burggraf wrote:
             | I just wrote an article on this (adding custom claims to
             | the JWT) for Supabase projects:
             | https://dev.to/supabase/supabase-custom-claims-34l2
        
             | rlili wrote:
             | You don't necessarily have to put those claims into a JWT
             | (other than the user ID). You can just store the "XYZ" that
             | the user has into a table.
        
               | burggraf wrote:
               | That is definitely true (and probably easier than doing
               | custom claims), but the reason I use claims is that it
               | saves doing a join against that extra table inside your
               | RLS policies, which can sometimes have a big performance
               | impact. Those claims are also available on the client
               | side, too, saving a round trip to the server if you need
               | to check the claims.
        
             | dragonwriter wrote:
             | > When you have RBAC based on multiple different
             | conditions, e.g. "does user have XYZ?" you will have to
             | architect your entire app around putting these claims into
             | JWT so the GraphQL engine can properly map those onto RLS.
             | 
             | If it's RBAC, why am I not just giving creating per-user
             | postgres roles inheriting from appropriate roles for the
             | relevant features?
             | 
             | > In a traditional app auth is on the app level and defined
             | in code, not a mix of code, SQL, JWT claims and
             | Hasura/Supabase configs.
             | 
             | Doing authz via DB-side permissions attached to per user DB
             | accounts is an equally, and more well-established,
             | traditional app approach.
        
       | jdc0589 wrote:
       | this is conceptually very cool, and graphql can be great, but
       | hooking graphql straight up to a persistent datastore as a means
       | of exposing things to external/front-end clients is an absolutely
       | terrible idea and nothing is going to change my mind.
        
         | datalopers wrote:
         | Data Exfiltration As A Service
        
           | eurasiantiger wrote:
           | I thought that was an Azure trademark...
           | 
           | But really, with proper authentication in place and
           | preferably built-in to a GraphQL-enabled datastore, a GraphQL
           | server can more secure than your average self-implemented
           | HTTP API.
           | 
           | The latter can easily leak through e.g. haphazard app-level
           | joins. Meanwhile, the GraphQL server can secure things at
           | object level, much like if people actually integrated their
           | frontend authentication all the way to their (No)SQL server.
        
         | theogravity wrote:
         | When I run PostGraphile, I have it behind another backend
         | because of this concern.
         | 
         | It does spare you from having to write SQL, but instead you
         | have to write the GQL documents. It also spares me from having
         | to come up with pagination SQL as PostGraphile handles that in
         | pagination cases, along with text searches.
         | 
         | PostGraphile also lets you selectively expose which tables /
         | fields should be available to a GQL client, but if PostGraphile
         | itself can be attacked, then yes, an FE client could get to the
         | underlying DB.
        
           | spoiler wrote:
           | What does this "middle end" do? Does it proxy to
           | PostGraphile, or does it do something with the query
           | beforehand? Or does it not proxy it at all?
        
             | theogravity wrote:
             | Can be a mix of both or a straight proxy to what the client
             | is allowed to access. For example, if you need to perform
             | multiple operations on the same resource in a single call,
             | the middle tier would do those multi-operations instead of
             | the FE client.
             | 
             | You're pretty much having the middle tier act as the
             | business logic layer as the FE client(s) doesn't have to
             | worry about calling a sequence of operations to do a task,
             | and instead just have to call a single operation on the
             | middle tier instead.
        
               | spoiler wrote:
               | Ah alright. So you do complex input (example)
               | transformation as part of the business logic in the
               | middle tier, and then forward it to the db? Does that
               | mean you parse the query in the middle end too, or just
               | parts of it (I'm not that knowledgeable about gql, so
               | sorry if the question makes no sense)?
               | 
               | We are soon going to be evaluating a similar idea at
               | work, so I'm just curious how it works. If it's lengthy
               | you don't have to go into too much detail if it's a
               | bother to explain!
        
               | theogravity wrote:
               | The middle tier does not have to be a GQL server; it can
               | be REST or some other protocol like gRPC. The middle tier
               | has a GQL client that calls the PostGraphile backend.
               | 
               | Yes to your question overall.
               | 
               | As another reply states, it's exactly a backend for a
               | frontend.
        
               | ramesh31 wrote:
               | It's called a "BFF" (Backend For Frontend)
               | https://blog.bitsrc.io/bff-pattern-backend-for-frontend-
               | an-i...
               | 
               | It's a really nice pattern particularly for multi-client
               | applications consuming the same resources. Instead of
               | trying to make a single REST api work for desktop,
               | mobile, and web, you can have a BFF for each which all
               | share the same GQL definitions and data access patterns,
               | but can have platform specific routing/handling/auth
               | logic.
        
         | spoiler wrote:
         | I understand that sentiment, since I was similar before, but
         | I've come to realise that it's little different from from
         | slapping an ActiveRecord-style ORM and framework on top of it.
         | The difference is where you encode access rules.
         | 
         | With frameworks they're in code, with graphql adapters, they're
         | declaratively managed (idk if this project does it, only
         | talking conceptually, but Hasura does it). This is kinda better
         | when you think about it because it's easier to
         | simulate/validated the ACL. And on top of that, it's possible
         | to build no-code interfaces on top of it to manage those rules
         | by anyone in an organisation. Add hooks and you can add complex
         | business along side these access rules, without encumbering the
         | business logic with ACLs.
         | 
         | I realise this is a bit idealistic, but I don't think it's an
         | unachievable goal with the current tech we have out there.
         | 
         | With all that said... Even though I sound like a proponent of
         | this now, I'd still be a bit nervous and on the fence about
         | having this in production.
        
       ___________________________________________________________________
       (page generated 2022-06-01 23:01 UTC)