-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement subscriptions for real-time updates #411
Comments
I think it'd be clearer to say "apply mutation/subscription payloads from the network layer" rather than more generally "from userland". |
The way we've been thinking of subscriptions is as a mix of push/pull semantics. In particular, the client would explicitly request updates from the server for a particular event, and the server could then notify the client when the event occurs (until the client closes the subscription). Here's the rough API we're considering: Public APIThe public API would be similar to mutations. The main difference is that subscriptions would have fixed/static queries (unlike mutations which intersect the fat query with those fields queried by the application).
class StoryLikeSubscription extends Relay.Subscription {
// Return a static query listing all fields to fetch when the event occurs
getSubscription() {
return Relay.QL`
subscription {
storyLikeSubscription(storyId: $storyId) {
likeCount
}
}
`;
}
// Describe how to handle the response payload (just like mutations)
getConfigs() { ... }
// Get the variables to send along with the query (e.g. the value of `$storyId`)
getVariables() { ... }
}
// Relay.subscribe(subscription, callbacks)
var subscription = Relay.subscribe(
new StoryLikeSubscription({storyId: ...}),
{
onNext: (data) => { ... }, // called whenever data is received
onError: (data) => { ... }, // called if an error occurs
}
);
subscription.dispose(); // notify the server to stop sending updates Internal ChangesThe rough steps to implementing the above are:
type RelaySubscriptionRequest = {
getDebugName: () => string;
getSubscription: () => RelayQuery.Subscription;
onNext: (data) => void; // called by the network layer whenever data is received from the server
onError: (err) => void; // called by the network layer if an error occurs. this ends the subscription.
}
|
I think that makes a good low-level API. My concern is that this doesn't necessarily match how I might want to think about subscriptions from the front end. Echoing @KyleAMathews's comment, I feel like I really think more about wanting live updates for a particular query, rather than wanting to subscribe to a specific named subscription. Moreover, I think having specific subscriptions requires closer coupling between the front end and the back end - unlike with mutations and few fields, if the server starts defining a new subscription type that I'm not handling from my front end, I'll lose some set of updates, some of which I might care about. Do you think it might be possible to define some higher-level subscription API that works on the level of nodes rather than on the level of "subscriptions"? I definitely want to define mutation-style |
I guess to be more concrete, suppose there were |
This is the issue for the |
This is an ideal end-state for subscriptions. However, this can be difficult to scale fully and correctly. For Relay core, we'd like to add support for patterns that we or the community have proven to be effective and practical to implement. For now, we'll pursue (and accept contributions for) the event-based subscription API that I described above because we've found this to be effective in practice. That said, we certainly welcome you to explore other options such as |
@josephsavona what are the steps to add support for a |
Just FYI to all those on this issue...I'm actively working on implementing the general concepts @josephsavona outlined above. Nothing in PR state yet...but hopefully it won't take me toooo much longer to get it there. |
@KyleAMathews thanks for starting this discussion! I've created a new task with the API described above to help guide contributions. Let's continue discussion at #541 |
also cc @skevy |
@taion 's idea is feasible if each node type is subscribable to. I did something like this with Entity Framework and signalR where each change to the database was published. So any tree of graphQL nodes on the client would result in a tree of subscriptions to the server. I then did additional filtering on the client so the server didn't do 'live queries' it just published events when a node's related nodes changed. |
In the subscriptions channel on Slack, a few of us (@taion, @skevy, and I) were discussing what are the missing pieces needed to implement subscriptions.
One important piece in Relay is the ability for a real-time network layer to apply "mutations" to the Relay Store. People will use different technologies to push data to their client. In each there needs to be a way to tell Relay this field changed or this node should be prepended to this connection, etc.
The text was updated successfully, but these errors were encountered: