Having a hard time conceptualizing how to properly marry Phoenix Channel and GraphQL paradigms.
Say your client server operations are synchronous and you choose GraphQL
Down the line you have to implement realtime operations between users. You could:
still use GraphQL: use subscriptions to subscribe to a topic to receive, and use the same mutation pattern you were before, to send. Most likely you will be using Channels to implement Subscriptions
just drop into Channels directly, in parallel
Clearly there is overhead in maintaining request handling for both GraphQL and Channels, but something tells me using GraphQL for realtime use cases beyond Subscriptions (as in SSE’s) is smelly. At the same time, it makes sense to route everything thru a single endpoint.
I know it can work, my question is more along the lines of best practices wrt either having both GraphQL and Channels coexist or consolidating them into GraphQL (or vice versa).
The frontend framework could be anything, but raises the same questions, whether it makes more sense having a GraphQL client and phoenix.js coexist or having all client/server interaction consolidated.
Arguably, GraphQL is a great fit for channels. The problem presented by channels is that by eschewing the traditional HTTP verbs, all of the standard patterns like REST don’t really apply.
GraphQL however is transport agnostic, so making queries via websocket works just fine, and subscriptions make it easy to stay up to date as information in the system changes. We’ve used GraphQL both with React / Apollo via websockets, as well as with separate live view services to great effect.
There is a small amount of boilerplate you need for supporting GraphQL over HTTP as well as channels, but it’s really small. More importantly, it’s a one time up front cost. As you grow your GraphQL schema, you don’t need to change anything.
Awesome, so basically layering GraphQL atop channels rather than having them coexist side-by-side.
This is very interesting and addresses one of my earlier questions: Replacing HTTP with Websockets (or other persistent transport). Why did you choose to transport queries via websockets rather than http? Are there any docs/articles written on this, specifically on the Absinthe side?
What I meant by “maintaining both” was having a scope for GraphQL and another for channels. I.e. you have, say, an Airbnb app whose browse/booking logic is routed to contexts by GraphQL resolvers but whose chat (or realtime bidding or wtv) is routed by channels. Is this an antipattern?
From a basic code perspective, Absinthe only uses a single channel __absinthe__:control and it’s a one liner to add it to your socket. Other than that it stays out of your way. However from a design perspective I agree that it introduces a question about whether to managing the chat via GraphQL or via traditional channels.
We started with HTTP, but once we setup the socket for subscriptions reusing that saves overhead. It isn’t a ton of overhead but hey each bit helps. It doesn’t super duper matter from Absinthe’s perspective so you can do whatever makes the most sense from an end client perspective.