[WIP] feat(wip:subsciption): Introducing subscription
🚧 Work In Progress - Introducing subscription
This aims to resolve #77.
Background
The GraphQL specification deliberately does not specify the transport layer.
Currently, WebSocket and HTTP are chosen by the majority, with these two different approaches.
- Full WebSocket: query, mutation, and subscription all on WebSocket.
- Hybrid: HTTP for query and mutation, while WebSocket for subscription. (Though theoretically arbitrary protocol can be chosen, there isn't another combination adopted wide enough.)
Opinion
As graphql-request has used HTTP for query and mutation, I assume the "Hybrid" approach is suitable for subscription, at least for now.
Protocol
For GraphQL over WebSocket, two different protocols exist, suggested by the community and adopted wide enough.
A. subscriptions-transport-ws (protocol spec): This is a legacy and not actively maintained, but many servers have implemented it.
B. graphql-ws (protocol spec): This is newly suggested one.
Those two are not compatible.
Thus graphql-request lets users choose one over the other by passing options.
Implementation (Pseudo Code)
class GraphQLClient {
subscribe(
payload: SubscribePayload,
options: SubscribeOptions
): () => void
unsubscribeAll(): void
}
subscribe returns a function that a consumer should call to unsubscribe.
SubscribeOptions includes Observer proposed by tc39/proposal-observable, which defines how to process received data, error, and completion.
TODOs
- [ ] Add more fields on
SubscribeOptions - [ ] Refactor constructor of the class
GraphQLClientfor configuring subscription options. - [ ] Create a facade function for users to import solely
- [ ] Write docs
- [ ] Test
are there any updates on this feature? this is something my team would really like, and i'd be happy to contribute if it's something the maintainers definitely want in a future release
@davevanfleet
if it's something the maintainers definitely want in a future release
This repo is active, but the maintainers do not develop/express priority for the suggested features. They only review PRs.
If you/your team need this feature, would you contribute?
@jjangga0214 i'd be happy to. i'll start taking a look over the weekend. i don't see a contributing guide in the repo, would you like me to open a PR against this feature branch when i have something ready?
Happy to help too
Happy to help when/how I can (limited time) the community drive this. As long as things are reasonable we'll merge it in. Clearly, adding support for a part of the GraphQL spec (subscriptions) is reasonable :). Maybe there will be some specific discussions around the implementation but can already say at a high level this is welcome.
@davevanfleet @Eduardoveras Great.
First, how about your creating suggestions on schema of SubscribePayload and SubscribeOptions?
Of course, if our opinions do not converge, you can create distinct PRs anytime, but I think this branch is a good starting point for now.
I wish you to create PRs against my branch, which is github.com/jjangga0214/graphql-request:feat/subscription.
@jjangga0214 would it make sense for the payload to use the RequestDocument type, and we can just validate that it's actually using a subscription query?
For SubscribeOptions the two options that come to mind for me right away are variables of type OperationVariables, and an onDataRecieved callback function.
I'd imagine an actual use of the subscribe function to look something like:
const { data, unsubscribe } = await client.subscribe(
JOBS_SUBSCRIPTION,
{
variables: {search: { starts_date: "whatever", ends_date: "whenever" } },
onDataRecieved: (data) => doSomething(),
}
)