Feature Request: WebSocket Support
Thank you for developing and maintaining the nuxt-graphql-middleware module! It's been very helpful for integrating GraphQL into Nuxt projects.
I was wondering if support for WebSockets, particularly for enabling real-time features like GraphQL subscriptions, is already implemented in the module. If it’s not currently available, are there any plans to add this functionality in the future? This would be a great addition for applications that require live updates.
If this is already on the roadmap or if there are any technical considerations (e.g., compatibility with Nuxt's architecture or specific WebSocket libraries), I'd love to hear more about it.
Hey there and thanks! 😄
I have thought about it in the past, as I personally also have a need for such a feature. However, the module pre 5.0.0 was a bit chaotic (coming from a previous Nuxt 2 version), so I haven't really tackled it. But in 5.0.0 I have added the very basic foundation to support subscriptions (in that they are partially "recognised" as an operation type), however there are no API endpoints or composables.
I will definitely explore possibilities to fully integrate subscriptions in such a way that they fit the goal of the module (act as a middleware).
So I implemented a proof of concept (it's actually quite "fleshed out" already) to support subscriptions. I was able to integrate it nicely with Nitro's support for WebSocket handlers, with a useGraphqlSubscription composable for easy integration.
There are still some challenges though, which are mostly due to a lack of experience with GraphQL subscriptions. Currently, I create a new graphql-ws client on the server for every connecting peer. This basically means that 100 users create 100 WebSocket connections to Nitro, which in turn creates 100 WebSocket connections to the GraphQL server. My reasoning is that this is the safest approach when things like authentication are required; from my understanding, authentication here is handled on the "connection" level. Basically, when a client connects to the GraphQL server via WebSocket, it will handle authentication via connectionParams. The server can then reject the connection.
Another approach would be to create just a single client on the server, which would likely be best for performance, since it only creates one WebSocket connection to the GraphQL server. But this would make it impossible to handle authentication on the connection level. Authentication would need to be handled on the subscription level, for example by passing a token in the extensions property of the subscription query. Then the GraphQL server would have to check authentication for each subscription request and could deny it there.
I would love to hear your inputs and insights into this topic!
Thanks for the update and the work on the subscriptions! I appreciate you taking the time to develop this. In my opinion, creating a new client per connection is preferable to a single shared connection, especially when considering the implications for authentication and security. Managing authentication at the connection level provides a more robust and secure approach. Looking forward to seeing this in release!