At a glance
- Identifier: #1026
- Stage: RFC X / Superseded
- Champion: @yaacovCR
- Latest activity: Added to WG agenda on 2023-06-01
- Spec PR: https://github.com/graphql/graphql-spec/pull/1026
Spec PR description
These spec edits should correspond to the working implementation of incremental delivery with deduplication currently posted as PR stack: https://github.com/graphql/graphql-js/pull/3894 => introduces Publisher https://github.com/graphql/graphql-js/pull/3886 => bulk of effort, introduces deduplication https://github.com/graphql/graphql-js/pull/3897 => adds pending
These spec edits do not currently include optional follow-on: https://github.com/graphql/graphql-js/pull/3895 => payload consolidation
[The diff to main might be helpful, but this is built on top of the amazing #742 and so the diff from that branch could be more useful.]
IMPORTANT NOTE:
These are hopefully trending toward complete in terms of the algorithm -- more explanatory prose should definitely be added.
<hr>TLDR?
The implementation and spec changes show how one can start executing deferred fragments semi-immediately (i.e. after deferring in an implementation-specific way), rather than waiting for the entire initial result to be emitted. This is not required -- one could still be compliant with the spec by deferring all the way until the initial result completes! In fact, how one defers is not per se observable and so the spec cannot mandate much about it with great normative force. But -- and I think this is important -- this PR and the implementation PR provide an algorithm/implementation/spec changes that give servers the flexibility to do what they think is right in that regard, and that might be desirable.
As of this moment, I am fairly confident in the implementation PR over at graphql-js, and the spec PR should generally correspond, demonstrating:
= the Field Group and Defer Usage record types that contain the information derived from the operation during field collection
= the introduction of a distinction between Incremental Data records and Subsequent Result records. Deferred Fragment records and Stream Items records exemplify Subsequent Results that are sent as a group to the client. But an individual Deferred Fragment Record may consist of a number of distinct Deferred Grouped Field Set records, which may overlap with other Deferred Fragment Records and should not be sent more than once. Deferred Grouped Field Set records are therefore a unit of Incremental Data and are tracked with a new record type. Stream Items records always contain a single unit of incremental data that is sent only once with little complication; they therefore represent both Subsequent Result and Incremental Data Records.
= the new Publisher construct, with a set of algorithms that create and manipulate Subsequent Result and Incremental Data records. Mutation of these records is not performed directly during execution, but only via interaction with the Publisher.
= the deferMap, which maps Defer Usage records to individual Deferred Fragment Subsequent Result records
** huge thanks to @urigo and @dotansimha of the guild for sponsoring my open-source work on this. **
Timeline
- Added to WG agenda on 2023-06-01
- Mentioned in WG notes on 2023-06-01
- Spec PR created on 2023-05-21 by yaacovCR
- Commit pushed on 2023-05-21 by yaacovCR: incremental delivery with deduplication and concurrent delivery
- Commit pushed on 2023-01-16 by yaacovCR: CollectFields does not require path or asyncRecord (#11)
- Commit pushed on 2023-01-15 by robrichard: replace server with service
- Commit pushed on 2022-12-05 by robrichard: fix typo
- Commit pushed on 2022-11-29 by yaacovCR: fix parentRecord argument in ExecuteStreamField (#7)
- Commit pushed on 2022-11-23 by robrichard: clarify label is not required
- 2 commits pushed on 2022-11-22:
- robrichard committed "Raise a field error if defer/stream encountered during subscription e…"
- robrichard committed "Add validation rule for defer/stream on subscriptions"
- Commit pushed on 2022-11-21 by yaacovCR: Add error handling for stream iterators (#5)
- Commit pushed on 2022-11-18 by yaacovCR: fix typos (#6)
- Commit pushed on 2022-11-16 by yaacovCR: remove ResolveFIeldGenerator (#4)
- Commit pushed on 2022-11-07 by yaacovCR: small fixes (#3)
- Commit pushed on 2022-11-01 by robrichard: update on hasNext
- Commit pushed on 2022-10-12 by robrichard: link to note on should
- 3 commits pushed on 2022-09-09:
- robrichard committed "typo"
- robrichard committed "improve non-null example"
- robrichard committed "Add FilterSubsequentPayloads algorithm"
- 11 commits pushed on 2022-09-08:
- robrichard committed "Add error boundary behavior"
- robrichard committed "defer/stream response => payload"
- robrichard committed "event stream => response stream"
- robrichard committed "link to path section"
- robrichard committed "use case no dash"
- robrichard committed "remove "or null""
- robrichard committed "add detailed incremental example"
- robrichard committed "update label validation rule"
- robrichard committed "clarify hasNext on incremental example"
- robrichard committed "clarify canceling of subsequent payloads"
- robrichard committed "Add examples for non-null cases"
- Commit pushed on 2022-08-24 by robrichard: clarify null behavior of if
- 2 commits pushed on 2022-08-23:
- robrichard committed "if: Boolean! = true"
- robrichard committed "address pr feedback"
- 7 commits pushed on 2022-08-18:
- robrichard committed "Introduce @defer and @stream."
- robrichard committed "Raise a field error if initialCount is less than zero"
- robrichard committed "wait for parent async record to ensure correct order of payloads"
- robrichard committed "spec updates to reflect latest discussions"
- robrichard committed "Note about mutation execution order"
- robrichard committed "minor change for uniqueness"
- robrichard committed "fix typos"
- Commit pushed on 2022-08-03 by robrichard: Align deferred fragment field collection with reference implementation
- 3 commits pushed on 2022-06-09:
- robrichard committed "add missing line"
- robrichard committed "fix ExecuteRequest"
- robrichard committed "fix response"
- 2 commits pushed on 2022-03-23:
- robrichard committed "fix wrong quotes"
- robrichard committed "remove label/path requirement"
- Commit pushed on 2022-03-08 by robrichard: Clarification on labels
- Commit pushed on 2022-03-07 by robrichard: add validation “Defer And Stream Directive Labels Are Unique”
- 2 commits pushed on 2022-02-07:
- robrichard committed "stream if argument, indexPath -> itemPath"
- robrichard committed "Clarify stream only applies to outermost list of multi-dimensional ar…"
- Commit pushed on 2022-02-02 by robrichard: deferDirective and visitedFragments
- Commit pushed on 2022-01-21 by robrichard: fix typo
- Commit pushed on 2021-12-30 by robrichard: add isCompletedIterator to AsyncPayloadRecord to track completed iter…
- 2 commits pushed on 2021-12-20:
- robrichard committed "Simplify execution, payloads should begin execution immediately"
- robrichard committed "Clarify error handling"
- 2 commits pushed on 2021-12-06:
- robrichard committed "data is not necessarily an object in subsequent payloads"
- robrichard committed "add Defer And Stream Directives Are Used On Valid Root Field rule"
- Commit pushed on 2021-11-26 by robrichard: fix typo
- Commit pushed on 2021-11-25 by robrichard: allow extensions only subsequent payloads
- Commit pushed on 2021-11-20 by robrichard: clarify negative values of initialCount
- Commit pushed on 2021-11-19 by robrichard: clarification on defer/stream requirement
- Commit pushed on 2021-05-15 by robrichard: Update Section 3 -- Type System.md
- 3 commits pushed on 2021-02-17:
- robrichard committed "fix typos"
- robrichard committed "clear up that it is legal to support either defer or stream individually"
- robrichard committed "Add sumary of arguments to Type System"