[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)