smallrye-graphql icon indicating copy to clipboard operation
smallrye-graphql copied to clipboard

Support subprotocol graphql-transport-ws

Open gabrielsson opened this issue 3 years ago • 8 comments

As described in #811 and outlined really nicely by GavinRay97 in the comments beeing able to consume graphql over an authenticated websocket with subprotocol graphql-transport-ws is not working with the GraphQLTransportWSSubprotocolHandler as it lacks the means of payload in the connection init message:

the connection message cannot have a payload GraphQLTransportWSSubprotocolHandler.java#L78

   this.connectionInitMessage = Json.createObjectBuilder().add("type", "connection_init").build();

while in the protocol it states the message is

interface ConnectionInitMessage {
  type: 'connection_init';
  payload?: Record<string, unknown>;
}

typically used for auth-tokens etc.

edit: Better defining the problem

gabrielsson avatar Oct 09 '22 20:10 gabrielsson

Hi @gabrielsson . Are you keen to do a PR to add this ? I assume you are looking for a way to add the payload to the init message ?

phillip-kruger avatar Oct 09 '22 22:10 phillip-kruger

@phillip-kruger Yes, I will take a look during this week!

gabrielsson avatar Oct 10 '22 06:10 gabrielsson

The payload field is optional, hence the question mark behind it in the protocol specification. Therefore saying that "graphql-transport-ws is not working" isn't correct - we only have a limitation in that we don't offer an API for applications to specify that they want to pass some payload to clients this way. Is this what you need? It could be achievable, we just didn't yet see any compelling use case for supporting it.

jmartisk avatar Oct 10 '22 06:10 jmartisk

Do you have any particular idea what the API should look like? How will the application define the payload items?

jmartisk avatar Oct 10 '22 06:10 jmartisk

@jmartisk I would say that in the best of worlds it should be possible alongside where we set headers on the connection

CLIENT_NAME/mp-graphql/header/KEY

something like

CLIENT_NAME/mp-graphql/initpayload/KEY

But that might be a stretch goal. As I am using the DynamicGraphQLClientBuilder.java I would start there.

gabrielsson avatar Oct 10 '22 07:10 gabrielsson

It might need a way to specify the values dynamically because they might change over time, in which case a simple configuration property wouldn't work, but rather an SPI that the application will implement

jmartisk avatar Oct 10 '22 08:10 jmartisk

I would look at the payload as something which is negotiating the connection. I agree that it might be useful to have a dynamical approach to set the initial payload, but as only one connection_init message can be sent during a connection, I believe it is a good idea to start treating the init payload as we treat the header property.

gabrielsson avatar Oct 10 '22 08:10 gabrielsson

~~There's one connection_init per connection, but over the runtime of a server, there will be tons of connections :)~~ Sorry yeah I somehow thought this was a server-side thing, disregard

But yeah, I'm not really sure how much dynamic it needs to be. It's not easy for me to imagine real-world use cases for this. Keeping it configuration-based will be much simpler to implement, and perhaps it will be enough, at least for start.

Also, how should we propagate this data to the server application? The server side library might want an API to be able to read this.

jmartisk avatar Oct 10 '22 09:10 jmartisk

fixed via https://github.com/smallrye/smallrye-graphql/pull/1590

jmartisk avatar Oct 24 '22 06:10 jmartisk