hasura / graphql-engine

Blazing fast, instant realtime GraphQL APIs on your DB with fine grained access control, also trigger webhooks on database events.
https://hasura.io
Apache License 2.0
31.14k stars 2.76k forks source link

FEATURE REQUEST: Save a named Query, Mutation, Subscription as a REST endpoint #3488

Open corepay opened 4 years ago

corepay commented 4 years ago

Concept:

Now that Hasura is saving the QSM for me I should be able to simply send the HASH in cURL or using a REST client or via REST from my app, Hasura receives this, pulls the QSM from storage and executes it. Hash can be sent as header param. For queries/subscription the params can be sent in query params. For mutations the values can be stored in body of request. All requests can still go to the v1/graphql endpoint.

Benefits:

  1. BIG -> Allows me save QSMs and easily retrieve them from the console and see what it is supposed to do instead of scrolling through hundreds of QSMs in the current HISTORY tab trying to remember which one I want.
  2. BIGGER -> I can use a saved QSM easily in my app without setting up a graphQL client and writing (duplicating) a lot of the QSM is my client app
  3. HUGE -> Using Hasura, I really do not need to learn how to develop grapqhl or write complicated resolvers or schemas on SERVER or IN MY APP - I just build my data structure in the console and use Hasura to create my QSM in the Explorer, grab the hash for the QSM and use already familiar REST methods to integrate with Hasura
  4. GAME CHANGER -> Since my app is using a hash to a QSM stored on Hasura I can change the structure/parameters on the QSM in Hasura and DO NOT need to change the code in my app.

The hash could be sent as a header value in all cases or as a query or path param on GET, UPDATE or as a query param on POST.

Ideally, this feature would be part of a HASURA REST SDK to make it even more simple to integrate Hasura on the client side.

Even better once I create a QSM I can get a code generated REST call for my client-side platform.

Let me know what you guys think. Not sure I can help with any PR but feel free to reach out if you want some more thought, opinion or assistance on the use or business case (I'd like to be the first to implement this!).

coco98 commented 4 years ago

@corepay Love it! Thanks for writing this up :)

I think it might be nicer to allow the creation of a named REST endpoint instead of a hash? I like this more because the REST endpoint can have a descriptive user-friend name.

corepay commented 4 years ago

IMO you can probably easily have an option to create a descriptive REST endpoint for single-focused context like Users or Items and still provide the hash - it is stored by id or hash anyway...

But a context named REST endpoint like /users wont apply in many cases where I build a QSM across multiple contexts - for example, your 3-factor app. In this case it would be similar to an RPC call….but typing this the thought occurred that I suppose you can make the endpoint reflect the service rather than the entity.

Sitting here thinking if I had this option I would probably do a mix in my apps. I would have a single endpoint for my 3-factor-app type requests and entity named endpoints where I am not doing a bunch of stuff outside normal CRUD.

One thing I like about the hash and single endpoint also is I do not need to manage and secure a bunch of endpoints as a developer. I have one endpoint - a distinction of graphql not provided by REST that this solution opens up to REST now

Like to keep in the loop on this if you move forward. FYI my idea where this would have a big impact is in developer portals with multiple devs and firebase-like Baas....

corepay commented 4 years ago

...also just thought about Events. You can provide pre-built QSM in Events and probably even allow chained events where a function calls the next hashed QSM and executes the query or mutation.

whaddaythinkaboutthat?

corepay commented 4 years ago

:) also just thought - you can extend permissions to the QSM in Hasura in total - for example if the QSM crosses users, posts, authors you can set permissions for the hash or named endpoint rather than individually for each entity (user/post/author). QSM or whatever you call the "bundled" hash or endpoint can override any already set table/row level permissions.

jorroll commented 4 years ago

Usually I've seen this feature referred to as persisted queries in the GraphQL world. For some prior art, see https://graphql-ruby.org/operation_store/overview.html#what-are-persisted-queries.

I'll note that persisted queries are usually saved by the client (rather than an admin creating a "special endpoint" in the Hasura console). Letting clients save their own persisted queries would be a better abstraction than what is described here, IMO. Though I could imagine that the Hasura console might provide a nice GUI allowing an admin to save a query.

I'll note that a major reason for using persisted queries, not listed above, is reducing the payload needed to trigger a vary large query (using a persisted query, you just need to provide a URL rather than an entire query or mutation document, for instance). Additionally, when saving a persisted query in graphql-ruby, you can "pre-parse" the query document, so that when calling the persisted query the server has less work to do.

Edit Actually I see graphql-ruby seems to have dropped pre-parsing from its operation store since I last used it. Perhaps pre-parsing was deemed too difficult to migrate between graphql-ruby releases.

corepay commented 4 years ago

Good point on the payload and I will check out persisted queries. One point I thought about maybe not stressed or explained well enough the value of having the query on server side is that it can be changed (within some limits) on the fly without having to change the client side code - as always a big plus for mobile apps and delays in app stores.

jorroll commented 4 years ago

I'll also note that Apollo has support for persisted queries: https://blog.apollographql.com/persisted-graphql-queries-with-apollo-client-119fd7e6bba5

guyf commented 4 years ago

👍

Bessonov commented 4 years ago

Don't miss the linked feature request above. It could be a very good combination.