graphql-wg icon indicating copy to clipboard operation
graphql-wg copied to clipboard

Consider allowing clients to set response priority with `@defer(order: Int)`.

Open theengineear opened this issue 2 years ago • 3 comments

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:

Example UI (1)

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 avatar Jul 27 '22 21:07 theengineear

@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.

benjie avatar Jul 28 '22 08:07 benjie

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

benjie avatar Jul 28 '22 08:07 benjie

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

theengineear avatar Jul 29 '22 17:07 theengineear

Closing as stale (related to #1413, though this isn't technically an action item); please use the discussion linked above for further feedback.

benjie avatar Nov 10 '23 12:11 benjie