Subscriptions-transport-ws: Design idea : separate concerns between transport and subscriptions protocol.

Created on 25 Jan 2018  路  1Comment  路  Source: apollographql/subscriptions-transport-ws

Hi there,

I've been thinking and reading a lot about how to perform authentication with subscriptions.
The official recommendation is to use connectionParam, and if you want to go further with live login/logout, people just suggest to close the connection and open a new one with the right params.

Since WebSocket is a real-time bidirectional transport mecanism, it seems to me that closing a connection and opening a new one just to send an information (this is what authentication is, nothing more than a piece of information) is by design an anti-pattern.

Then, I thought I could just use the WebSocket to send messages myself and implement my own protocol... but accessing it is not part of the interface. In fact, the interface is solely dedicated to GraphQL.

Now, this is where I think there is a design mistake : SubscriptionServer and SubscriptionClient are handling both the transport and the protocol.

I think we sould split the job into two parts :

  • The first one is the protocol handling. It should follow the GraphQL Subscriptions Protocol as specified, making the bridge between a Client or Server, and a Transport Mecanism. It should be used as some kind of a middleware.
  • And the second part is the actual transport mecanism. It could be the current WebSocket handler implementation (with its connectionParam, reconnect, and hooks features), but anybody could implement its own using different transport protocols. If you're using GraphQL between two servers, maybe you'd be happy to use directly a TCP socket instead of having HTTP servers at each end to understand WS.

This idea is basically what has already been done in Apollo 2.0 for instance. The Apollo client handles the GraphQL part, and uses Links as abstractions of the Network layer. They've also abstracted out caching, instead of using Redux.

Advantages of such a design are multiple :

  • It allows using any transport mechanism, not only websocket.
  • It allows using one transport mechanism for multiple purpose. Maybe people will need additional protocols between the same client/server. Then it would be stupid to open multiple connections between them.
  • Thus, it would be easier to handle authentication flows. You could use the transport part to send custom messages about authentication (and not be limited to that one time connectionParam thing).
  • It avoids loosing data. Indeed when closing and reopening a connection, there is a delay during which you're not subscribed to anything. If you have a good connection and very few notifications, that's ok, but if the WebSocket connection takes time to establish, and your app send updates every milliseconds or so, it can be devastating.

_For a fully featured authentication process, we would still need a way to update the subscriptions state once we know the user has logged in/out.
For example, we could add a function SubscriptionServer.changeContext called by authentication middlewares. This would call subscribe with the new context on all active subscriptions to get new AsyncIterators. This is just a quick concrete example, but it is out of the scope of this discussion which focuses on separation of concerns._

Please, feel free to give remarks and thoughts about such a design change.

Most helpful comment

+1 As a practical example this separation of concerns could allow webRTC or a higher-level abstractions such as the Signal Protocol to be used as an alternative transport layer which could enable developers to us GraphQL for peer to peer communications. This would be extremely useful for me.

>All comments

+1 As a practical example this separation of concerns could allow webRTC or a higher-level abstractions such as the Signal Protocol to be used as an alternative transport layer which could enable developers to us GraphQL for peer to peer communications. This would be extremely useful for me.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

farzd picture farzd  路  3Comments

prokher picture prokher  路  5Comments

jedwards1211 picture jedwards1211  路  4Comments

corysimmons picture corysimmons  路  5Comments

PetrSnobelt picture PetrSnobelt  路  3Comments