-
Notifications
You must be signed in to change notification settings - Fork 405
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: allow custom gql-on-ws protocol for subscriptions #1348
Conversation
I was reading the PR and it looks good to me, It would be great to be able to switch to the |
The subscriptions configuration now accepts a custom `protocol`, to change the gql-on-ws protocol from the default `subscriptions-transport-ws.
Hi @kamilmysliwiec, I've finally managed to do some thorough testing of this PR with the subscription services I'm working on, and they seem to work without problems (after upgrading the clients). I have tested this with an Electron application using React, and with two React Native applications. I was able to migrate the authentication (performed in the |
Hey ! |
Apologies for the delay. Currently we're focused on getting v8 out the door. Once it's published we will work on merging in PRs again. Kamil has been very busy with getting this going. |
Thanks for the answer. |
LGTM! |
Hi, Given that Apollo 3.0 has removed subscriptions-transport-ws completely, we are stuck. We would like to upgrade to graphql-ws but cant wait until nestjs 9.0 to be release. When do you expect that to go live? probably a year from now? any chance you can backport this to 8.0? |
I'll release v9 (exclusively for |
Hi @kamilmysliwiec! Thanks for merging this!
When we migrated from |
@asmeikal this sounds great! Would you like to create a PR for this (both dep upgrade + backward compatibility)? I'm hoping to get v9 ready asap to unblock people that want to use Apollo v3. I'll release it separately from other packages :) UPDATE: I've done some groundwork for the backward compatibility already (9.0.0 branch). I had to remove a dedicated error class added in this PR @asmeikel, let me know if you think there's a better way & approach! I gotta add more tests too |
Hi @kamilmysliwiec, Do you still need help with integrating the new |
I removed the error handling layer because we no longer maintain the ws server internally but instead, we reuse the existing one (with
If you can give it a shot, that would be awesome! |
OK we tested the 9.0.0-Next.2 package. it works. :-) The main issue we have is the path is hardcoded to '/graphql' . we need that to be configurable so that we can map it to something different so that on our load balancer we can set different timeout for each path. Haven't tested the exceptions yet. But will give that a try today |
Thanks for the feedback @ddehghan! Would you like to create a PR to address this? |
I did some more investigation: Actually it seems that '/graphql' path has no effect only the domain portion is actually used.. The Client can request any url on the port and it gets connected. so there must be a bug somewhere else. Because any url works we are able to set a different timeout of that load balancer so it works for us at the moment. web socket does support path. But I think the way they do it is they give you a call back on connection with the url and you are supposed to handle that. I don't think graphql-ws has implemented that so passing the path is a no-op. |
Hi there, got around to testing the 9.0.0 branch! About the ws server, the About the compatibility with Last thing: about the error messages, I have strong opinions against using the socket directly. :) I believe that a custom WebSocket exception with a code for the WebSocket CloseEvent is the right choice, for a few reasons:
|
Great catch! Would you like to include a fix in your PR or do you want me to do so?
🕐 todo
Sounds good!
Totally agree with you. I'm against using the socket directly as well, I'm just afraid of putting too much magic/hardcoding custom logic & auto-wrapping callbacks in this package. As implementing such an error layer doesn't really require changes in the Would you like to create 2 separate PRs to the v9 branch in which the latter one would contain errors layer-specific changes (so we can look at both separately)? 🙌 |
Hi @kamilmysliwiec, I can try and put together two PRs for these changes! I hope to get at least one done by tomorrow! |
Amazing, thank you @asmeikal! |
Not sure if this is the right place to ask, but we just migrated from Nest 7 -> 8 and the subscriptions on the mobile apps are no longer working - possibly due to updating to Currently our subscriptions are no longer working. I've tried following https://docs.nestjs.com/graphql/subscriptions#enable-subscriptions-with-apollo-driver and added: subscriptions: {
'subscriptions-transport-ws': true,
}, However, subscriptions will still fail. I might be missing something. I've also found https://www.apollographql.com/docs/apollo-server/migration/#reenabling-subscriptions but I am not sure if this is relevant for Nest.js projects that use the Any pointers in the right direction would be greatly appreciated! |
This could close #1341 for the moment, and provide a way to use
graphql-ws
instead ofsubscriptions-transport-ws
without breaking existing NestJS services that already use subscriptions.PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
What is the current behavior?
Issue Number: #1341
As described in the issue, the GraphQL module currently relies on
subscriptions-transport-ws
, which has several issues and is being deprecated in favor ofgraphql-ws
. Apollo will change the gql-on-ws protocol in the future, but I don't believesubscriptions-transport-ws
to be production ready, and cannot wait for Apollo to switch protocols nor renounce to NestJS.What is the new behavior?
It's now possible to specify a
protocol
when passingsubscriptions
options to the GraphQL module.The new protocol is
graphql-ws
, and has a few differences in the signature of the callback that the user can provide.The signatures match the ones documented in
graphql-ws
.Does this PR introduce a breaking change?
Other information
The
GraphqlWsSubscriptionService
is taken from the example implementation provided bygraphql-ws
. The purpose of this class is to connect the WebSocket server, thegraphql-ws
server, and Apollo. The main difference with the example implementation is in how errors are handled.The
GraphqlWsException
class can be used to close the WebSocket connection with a specific code and reason, as suggested in thegraphql-ws
documentation to implement custom authentication protocols (see here). TheonConnect
callback can use this exception to signal errors to the client, and the client may behave differently based on the error, e.g., it may refresh the authentication token if it is expired. The tests cover this part.The
graphql-ws
server is highly customizable via callbacks, that are called by the protocol in different phases of the subscription. Most of these are quite advanced and "low level", and allow manipulation of theExecutionArgs
or of the protocol message, so I only included theonConnect
,onDisconnect
, andonClose
ones in the GraphQL modulesubscriptions
configuration.A catch: while the new library is called
graphql-ws
, its WebSocket sub-protocol is calledgraphql-transport-ws
, and the WebSocket sub-protocol ofsubscriptions-transport-ws
is calledgraphql-ws
! 😞 Maybe theprotocol
option passed to thesubscriptions
configuration should be named after the actual WebSocket sub-protocol, and not after the library, to avoid confusion.