GraphQL server used by different clients?

Hey,

So I’m new to the Holochain ecosystem, and I have some questions on how this all fits together.

Let’s say I’m building an app that I plan to be able to port over to Holochain at a later point.

I have a normal React web app and a React Native app. They are both communicating with the same GraphQL endpoint on a Node.js server somewhere that communicates with my backend. Then at a later point, I want to change the resolvers in the server to do Zome-calls to a Holochain application instead of to my original database.

Can a node.js server communicate with a Holoport and work as just an API endpoint for example, or do I have to move the GraphQL server to the UI-layer together with the hApp bundle? I’ve seen most hApp projects have the GraphQL server written client-side together with the UI. I guess this makes sense as you are running both frontend and backend code in the bundle.

What would be a good strategy if I’m writing an application that I’m planning to move to Holochain, but I want to use different clients like Vue/React/React-Native/Electron and not repeat the GraphQL code on each client?

1 Like

I’m interested in this also. We’ve seen GraphQL being used in frontend middlewares, but I think those resolvers should be reimplementeable in a backend GraphQL server so you wouldn’t have to change the frontend calls.

Zomes can also be compiled with Juniper for GraphQL servers, though that isn’t recommended. Exactly why I do not know yet. See: GraphQL and Holochain

Hi @leifriksheim and @ldwm! So yes, interesting discussion this one as always, with @tats_sato we wrote this article detailing a little bit of the why of this approach: How to build a GraphQl - Holochain middleware – Holochain Open-Dev Blog – Holochain developer blog, by and for the holochain community.

So, in here, the two “release scenarios” that (will) exist in hololand are very different from each other:

  • On holochain, you are running the node on your local machine. This means that network requests to your localhost are almost instantaneous. I don’t think that it’s worth it to do graphql request to a hosted server and then back to your own machine in this scenario, since you could directly call yourself. This is the only scenario available to us right now through holoscape.

  • On holo, we are going to call a hosted holochain application on a holoport. In this case, we do have to request a process running on an external machine, so reducing the number of calls would have at least a partial improvement on the performance. I think though that the main scenario that holo is going to support through frontend libraries (see here is having the UI call directly call holo’s infrastructure, so I don’t know how much flexibility we are going to have here… Also, “proxying” the request through a Node.js server seems to me to solve the JS bundle size issue, but not the “reduce network requests” issue, and adding a possible centralized point susceptible to attacks… I think when holo launches with all details and infrastructure we’ll see what’s possible and what isn’t, maybe the best strategy would be a zome with Jupiter compiled with resolvers to your particular happ, but we have to see what real impact these are going to have in the performance.

Also note that on both cases, the majority of network requests will be done by the holochain nodes pinging and hopping with each other to navigate the DHT, not from the UI to the holochain node. So, yes we could reduce the number of requests from the UI to the node, but this would only partially speed up the process.

I don’t follow exactly: couldn’t you reuse all graphql middleware in all frontend frameworks? The ApolloClient stack for example is pretty much framework agnostic: although it offers different adapters/APIs to call from the components, the “middleware” layer stays pretty much the same, no? Am I missing something?

So, at least this is what I’m thinking/how I frame the problem, maybe we are missing something to fix all of our issues… Let me know if you have some ideas around this :slight_smile:

Isn’t this dependent of the collaborative application you’re creating? Querying nested structures for a Google docs-like app quickly adds up the requests.

Not really, unless in your app you have a redundancy factor of 100%… Any get_entry/get_link will do normally 2/3 network requests or hops to fetch the data in the DHT, since that holochain node doesn’t have all the data in it. Or are you suggesting using another pattern?

The ApolloClient stack for example is pretty much framework agnostic: although it offers different adapters/APIs to call from the components, the “middleware” layer stays pretty much the same, no? Am I missing something?

I would agree that this is true.

maybe the best strategy would be a zome with Jupiter compiled with resolvers to your particular happ

This could be a good approach in HOLO-hosted apps, as it means all requests between the GraphQL resolvers and Holochain are run locally through the Holochain conductor, no? However, the bytecode for such a zome is no small thing- it has most of a webserver as well as web UI content packaged up inside it.

Instead I prefer to write my optimisations on the client using a composable request caching API.

We’ve seen GraphQL being used in frontend middlewares, but I think those resolvers should be reimplementeable in a backend GraphQL server so you wouldn’t have to change the frontend calls.

That’s correct, as long as your “backend” tech is JavaScript. The way you’d write resolver callbacks binding a Mongo database to a node application is identical to how you’d write browser-side resolver code for a direct Holochain binding. If you break the schema into a separate module to the resolvers you can re-use it in both locations.

1 Like