Soluto / stitch

Stitch is a no-code GraphQL tool for your existing APIs and data sources
MIT License
29 stars 8 forks source link

Add subscription support #78

Open AvivRubys opened 5 years ago

AvivRubys commented 5 years ago

We should support subscriptions. We will need a use case first, since it can be done a few different ways, so maybe there are different implementations that can be used here - websockets, socketio, sse, etc

AvivRubys commented 5 years ago

This is much more complex than I initially thought, but some things we should think about:

Response Stream (Client connection)

We could offer full websocket connections (i.e. use websockets for queries and mutations as well), or add a /subscriptions websocket endpoint. Either way, it sounds like apollo's ws transport is the de-facto standard so we should implement a compatible transport layer

Source Stream (Upstream connection)

There's a ton of options here, all of them dependant on where the data is coming from. We could implement @kafka, @azureServiceBus, etc. directives, or we could maybe create an additional service to handle those internally and maintain a consistent interface with it.

Synchronisation between instances

To support multi-instance gateways we will need a local pubsub layer like redis, nats, etc

AvivRubys commented 5 years ago

The more I think, I realize there are two distinct types of subscriptions - Event style, and Query style. Imagine we have a backend pubsub topic with events published for new employees hired. Consider these subscriptions:

type Subscription {
  employeeHired: Employee
}

This represents an event. In production, you would probably just forward the event from your backend topic directly to this subscription.

type Subscription {
  employees: [Employee]
}

This represents state. In a real scenario, you'd query your schema for employees whenever you get an event in the topic, effectively using the event just to know when to re-fetch, and probably completely discarding it's data or using it as arguments to the query.

The first type doesn't even need the rest of the schema. It's just using GraphQL as a convenient way to pass typed events to the frontend. Whereas the second type consumes the schema and is deeply integrated with the rest of it.

Both are legitimate uses, depending on if you need state or events. Which do we support and how are good questions we need to think about.