Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GraphQL subscription using server-sent events & EventSource

I'm looking into implementing a "subscription" type using server-sent events as the backing api.

What I'm struggling with is the interface, to be more precise, the http layer of such operation.

The problem:

Using the native EventSource does not support:

  1. Specifying an HTTP method, "GET" is used by default.
  2. Including a payload (The GraphQL query)

While #1 is irrefutable, #2 can be circumvented using query parameters.

Query parameters have a limit of ~2000 chars (can be debated) which makes relying solely on them feels too fragile.

The solution I'm thinking of is to create a dedicated end-point for each possible event.

For example: A URI for an event representing a completed transaction between parties:

/graphql/transaction-status/$ID

Will translate to this query in the server:

subscription TransactionStatusSubscription {
    status(id: $ID) {
        ready
    }
}

The issues with this approach is:

  1. Creating a handler for each URI-to-GraphQL translation is to be added.
  2. Deploy a new version of the server
  3. Loss of the flexibility offered by GraphQL -> The client should control the query
  4. Keep track of all the end-points in the code base (back-end, front-end, mobile)

There are probably more issues I'm missing.

Is there perhaps a better approach that you can think of? One the would allow a better approach at providing the request payload using EventSource?

like image 313
elad.chen Avatar asked Mar 16 '19 17:03

elad.chen


People also ask

Do GraphQL subscriptions use WebSockets?

What are GraphQL Subscriptions? Subscriptions are a GraphQL feature allowing the server to send data to its clients when a specific event happens. Subscriptions are usually implemented with WebSockets, where the server holds a steady connection to the client.

How do you use subscriptions in GraphQL?

Open your favorite browser and navigate to http://localhost:3000/graphql, you will see the playground UI appear, so run the subscription. The playground will start listening to event updates from the GraphQL server. Create a second tab and load http://localhost:3000/graphql on it.

What are GraphQL subscriptions used for event based real time functionality?

What are GraphQL Subscriptions? GraphQL subscriptions allow you to add event-based realtime functionality to your app. A client can subscribe to specific events that are happening on the server-side. Then, whenenever that event actually happens, the server will send the corresponding data over to the client.

What is the difference between a GraphQL query and subscription?

Like queries, subscriptions enable you to fetch data. Unlike queries, subscriptions are long-lasting operations that can change their result over time. They can maintain an active connection to your GraphQL server (most commonly via WebSocket), enabling the server to push updates to the subscription's result.


1 Answers

Subscriptions in GraphQL are normally implemented using WebSockets, not SSE. Both Apollo and Relay support using subscriptions-transport-ws client-side to listen for events. Apollo Server includes built-in support for subscriptions using WebSockets. If you're just trying to implement subscriptions, it would be better to utilize one of these existing solutions.

That said, there's a library for utilizing SSE for subscriptions here. It doesn't look like it's maintained anymore, but you can poke around the source code to get some ideas if you're bent on trying to get SSE to work. Looking at the source, it looks like the author got around the limitations you mention above by initializing each subscription with a POST request that returns a subscription id.

like image 59
Daniel Rearden Avatar answered Jan 03 '23 21:01

Daniel Rearden