Open mitar opened 4 years ago
I implemented JSON patch diffs for Apollo Server over at graphql-live-subscriptions perhaps this schema could serve as a starting point for a JSON patches in Hasura discussion.
I wouldn't bother looking at how I generated those JSON patches though it sounds like y'all already have a much better system for that with SQL polling :)
This is actually more important than just saving traffic, please check out this issue https://github.com/apollographql/apollo-client/issues/6127
I do not think diffing would help with the issue you linked to. This is just disconnect between how subscriptions are applied win apollo client. What happens if you have local change + change for that particular field comes through diff? So diffing would just make the problem less obvious. The solution is that apollo client would have to know which change from the server relates to the optimistic change on the client and know when that optimistic change has been confirmed (when the value is the same is good heuristic, but not perfect) and when overrode by the server.
The developer behind RxDB released a library a few days ago targeting this exact problem. This is not a viable solution because it's in Javascript, but from an architectural perspective it could offer up some ideas for a later implementation or anyone looking to do this on the client-side or as a middleware-server method:
I do not think diffing would help with the issue you linked to. This is just disconnect between how subscriptions are applied win apollo client. What happens if you have local change + change for that particular field comes through diff? So diffing would just make the problem less obvious. The solution is that apollo client would have to know which change from the server relates to the optimistic change on the client and know when that optimistic change has been confirmed (when the value is the same is good heuristic, but not perfect) and when overrode by the server.
I saw this scenario like this: 1) How we have now, problematic:
[Item0, Item1, Item2]
[Item0, Item1', Item2]
[Item0, Item1', Item2]
[Item0', Item1', Item2]
[Item0', Item1', Item2]
[Item0, Item1', Item2]
because lag[Item0', Item1', Item2]
because lag2) How it should be with diff:
[Item0, Item1, Item2]
Item1'
[Item0, Item1', Item2]
Item0'
[Item0', Item1', Item2]
Item1'
because lagItem0'
because lagYes there is this case when both times we've updated the same item, then the interface will jump anyway. But it's much easier to control than lock the whole interface while single item is waiting for the server confirmation
Checking in on this – any movement?
maybe this https://github.com/hasura/graphql-engine/pull/7946 will fix it? or at least a step into that direction..
maybe this https://github.com/hasura/graphql-engine/pull/7946 will fix it? or at least a step into that direction..
Streaming is great for some scenarios, like when you have events organized by timestamps, and you want all events.
However, a live query diff patch would be for other scenarios, like a filtered, sorted and paginated resultset (it's not possible to do with streaming, because it supposes you want to receive all data - when what you want in this scenario is to have a "reactive slice" of the data, produced by a subscription).
IMHO, adding something like a @diff
extension would be a great improvement. The "cost" of using it would be storing in the server the last result sent to each query (to run the json diff), which would be perfectly acceptable for our use case.
Also, I think that we could state that using the @diff
extension is not encouraged when doing optimistic updates, so we (the server) don't need to worry about it.
Currently, live queries re-send whole state every time. Even for mid-sized queries with few KBs of data, this can mean quite some traffic.
Would it be possible to provide some way to enable diffing and sending only changes? Maybe computing a JSON patch against a previous version and send that over? That would probably require storing query results on the server though, to do such diffing, so it should be configurable if you want that.
(Alternatively, Hasura could store just some merkle-like-hash-over-json-structure on the server, instead of whole state, to compute parts of the state which changed, without having to store whole state, and then send patches only for that.)