Add Server-Sent Events transport

Prior to this commit, the WebFlux and WebMVC infrastructure would only
support subscriptions over the WebSocket and RSocket transports.

This commit adds the `GraphQlSseHandler` implementations for both web
frameworks. This handler will send GraphQL responses as as stream of
Server-Sent Events, over an HTTP response with the "text/event-stream"
content type.

This implementation only supports the "Distinct connections mode" and
will reject all operations other than Subscriptions.

This commit also enhances the `HttpGraphQlTransport` client transport to
support subscriptions over this new protocol.

Closes gh-309
This commit is contained in:
Brian Clozel
2024-02-15 21:09:27 +01:00
parent 3dcbd8c2e9
commit 1f7063c9b4
19 changed files with 969 additions and 73 deletions

View File

@@ -467,10 +467,12 @@ You can use the `GraphQlClient` xref:client.adoc#client.graphqlclient.builder[Bu
[[client.subscriptions]]
== Subscription Requests
`GraphQlClient` can execute subscriptions over transports that support it. Only
the WebSocket and RSocket transports support GraphQL subscriptions, so you'll need to
create a xref:client.adoc#client.websocketgraphqlclient[WebSocketGraphQlClient] or
xref:client.adoc#client.rsocketgraphqlclient[RSocketGraphQlClient].
Subscription requests require a client transport that is capable of streaming data.
You will need to create a `GraphQlClient` that support this:
- xref:client.adoc#client.httpgraphqlclient[HttpGraphQlClient] with Server-Sent Events
- xref:client.adoc#client.websocketgraphqlclient[WebSocketGraphQlClient] with WebSocket
- xref:client.adoc#client.rsocketgraphqlclient[RSocketGraphQlClient] with RSocket

View File

@@ -32,6 +32,27 @@ it contains, for the actual config.
The 1.0.x branch of this repository contains a Spring MVC
{github-10x-branch}/samples/webmvc-http[HTTP sample] application.
[[server.transports.sse]]
== Server-Sent Events
`GraphQlSseHandler` is very similar to the HTTP handler listed above, but this time handling GraphQL requests over HTTP
using the Server-Sent Events protocol. With this transport, clients must send HTTP POST requests to the endpoint with
`"application/json"` as content type and GraphQL request details included as JSON in the request body; the only
difference with the vanilla HTTP variant is that the client must send `"text/event-stream"` as the `"Accept"` request
header. The response will be sent as one or more Server-Sent Event(s).
This is also defined in the proposed
https://github.com/graphql/graphql-over-http/blob/main/rfcs/GraphQLOverSSE.md[GraphQL over HTTP] specification.
Spring for GraphQL only implements the "Distinct connections mode", so applications must consider scalability concerns
and whether adopting HTTP/2 as the underlying transport would help.
The main use case for `GraphQlSseHandler` is an alternative to the
xref:transports.adoc#server.transports.websocket[WebSocket transport], receiving a stream of items as a response to a
subscription operation. Other types of operations, like queries and mutations, are not supported here and should be
using the plain JSON over HTTP transport variant.
[[server.transports.http.fileupload]]
=== File Upload