Hmm. I wonder if there is some kind of query builder that can live server-side. That is, capture the flexibility of a query language when developing, and then consolidating that when going into production.
Though I guess you can do that with REST too.
I'm currently exploring all of this myself. I have a side project in mind that can use a graph db, and I thought a front-end graphql can work well with a graphdb backend. I was not sure why this pattern is not more popular, but reading all of this now, I'm seeing where these problems may arise.
A graph db backend can use efficient graph search algorithms, especially for deeply nested data, but the issue with authorization is still there. If anything, fine-grained authorization is something better represented with graph dbs than with relational databases.
This is a vague recollection, but I seem to recall Meta/Facebook engineers on HN having said they have a tool that allows engineers to author SQL or ORM-like queries on the frontend and close to where the data is used, but a compiler or post-processor turns that into an endpoint. The bundled frontend code is never given an open-ended SQL or GraphQL interface.
And perhaps not coincidentally, React introduced "server actions" as a mechanism that is very similar to that. Engineers can author what looks, ostensibly, like frontend code, merely splitting the "client" side and "server" side into separate annotated functions, and the React bundler splits those into client code, a server API handler, and transforms the client function call into the annotated server function into an HTTP API call.
Having used it for a bit it's really nice, and it doesn't result in yielding so much control to a very complex technology stack (GraphQL batchers, resolvers, etc. etc.)
> I seem to recall Meta/Facebook engineers on HN having said they have a tool that allows engineers to author SQL or ORM-like queries on the frontend and close to where the data is used, but a compiler or post-processor turns that into an endpoint.
> perhaps not coincidentally, React introduced "server actions" as a mechanism that is very similar to [the above]
Yep - there's also the Scala framework LiftWeb (https://www.liftweb.net/), the Elixir framework Phoenix (https://www.phoenixframework.org/) and of course the system we're using right now (Arc) that do similar things. Scaling these kinds of UUID-addressed-closures is harder (because the client sessions have to be sticky unless you can serialize closures and send them across the network between servers).
Code generation is very common at Meta. One just needs to create a query or fragment. A fragment can be spread at the root query level using relay so it will do the fetch once. It gets more complex because you can lazily query more data based on parameters you pass into GQL. It feels like magic and is really annoying imo.
> Hmm. I wonder if there is some kind of query builder that can live server-side. That is, capture the flexibility of a query language when developing, and then consolidating that when going into production.
I think this is what a lot of people end up doing (and yes, with REST). Translating options via query params / POST body into a query. In theory GraphQL was supposed to mitigate this DSL-like translation, but the thing is people like flexibility and ability to change and, yes, break backwards compatibility. That's also why a lot of people end up with a translation layer with things like RPC, which is itself supposed to be a direct, shared communication protocol.
The messiness of APIs is often a feature, at least internally. These approaches that attempt to avoid the mess are better for the end consumer but cause friction within development groups and the benefits are often obscured.
Assuming the query language for the graph DB you have in mind is declarative like SQL, I recommend templated queries. I have found this technique scales pretty well for query complexity, makes it relatively trivial to "get to the query" if something needs to be debugged in the details more easily outside of the app, and it makes performance-oriented optimization work far easier.
I've had my share of headaches with the various flavors of ORM and GraphQL and always come back to query templates, e.g. MyBatis in the JVM ecosystem or Go's template package. There is still value in abstracting this from the REST web service interface to make it possible to change the app<->database connection without disrupting REST clients. It's possible to reuse parameter structs/classes between the REST client and DB+template client layers to avoid a lot of rote translation. It seems simple and repetitive, but actually saves time compared to the GraphQL/ORM complexity as apps & query complexity scale, in my experience.
> Hmm. I wonder if there is some kind of query builder that can live server-side. That is, capture the flexibility of a query language when developing, and then consolidating that when going into production.
Back when GraphQL started being around, I prototyped a proxy server that accepted a JSON dsl to resolve a series of calls to a backend JSON/REST API, so that the chain of calls would be batched up closer to the server.
Worked pretty well. Definitely something that could be make to. Kind of graphql themed but how it translates to REST can be explicit.
Though I guess you can do that with REST too.
I'm currently exploring all of this myself. I have a side project in mind that can use a graph db, and I thought a front-end graphql can work well with a graphdb backend. I was not sure why this pattern is not more popular, but reading all of this now, I'm seeing where these problems may arise.
A graph db backend can use efficient graph search algorithms, especially for deeply nested data, but the issue with authorization is still there. If anything, fine-grained authorization is something better represented with graph dbs than with relational databases.