graphql-wg
graphql-wg copied to clipboard
Consider allowing clients to set response priority with `@defer(order: Int)`.
Context
My team is looking to begin using the experimental @defer
and @stream
directives. The spec appears to leave prioritization up to the server. I think this control structure may be backwards.
For reference, the portion of the specification giving me pause is as follows:
A query with
@defer
directive will cause the request to potentially return multiple responses, where non-deferred data is delivered in the initial response and data deferred delivered in a subsequent response.
Proposal
Can we allow the client to specify an order
? It would guarantee that data for order: N
not be returned before data for order: M
.
query {
search(text: "Han Solo") {
... CharacterFields
friends @defer(order: 1) {
... CharacterFields
friends @defer(order: 2) {
... CharacterFields
}
}
totalCredits: @defer(order: 1)
}
}
fragment CharacterFields on Character {
name
image
}
Problem
Here's a visualization of the problem:
Under-the-hood, this UI is powered by the following query (which can cause the "erroneous incremental load" pictured above):
query {
search(text: "Han Solo") {
... CharacterFields
friends @defer {
... CharacterFields
friends @defer {
... CharacterFields
}
}
totalCredits: @defer
}
}
fragment CharacterFields on Character {
name
image
}
Disclaimer
I haven't considered how this might interoperate with the @stream
directive. I've also not considered validity checking on nested @defer
or @stream
directives — I'm just hoping to raise a potential concern about the core control structure here.
❤️ — Thanks very much for taking the time to read this. Apologies for any / all naivety and apologies if this has been covered (my initial searches didn't turn anything up).
@theengineear You should cross-post this to https://github.com/robrichard/defer-stream-wg/discussions/ as that's where the stream/defer WG hang out.
Though I should note that at the moment we already enforce that the payloads must be returned in an order such that the path to insert to already exists. In your example, each search.friends[x].friends[y]
will always be delivered after the relevant search.friends[x]
because otherwise the path to write to doesn't exist, so the order makes no difference here.
I think this is the discussion you've been looking for: https://github.com/robrichard/defer-stream-wg/discussions/17
Thanks so much @benjie! That's exactly the kind of discussion I was looking for!
Cross-posted 👉 https://github.com/robrichard/defer-stream-wg/discussions/44
Closing as stale (related to #1413, though this isn't technically an action item); please use the discussion linked above for further feedback.