-
Notifications
You must be signed in to change notification settings - Fork 2k
Add support for newer incremental delivery format #8148
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
Open
jerelmiller
wants to merge
92
commits into
main
Choose a base branch
from
jerel/newer-incremental-spec
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 84 commits
Commits
Show all changes
92 commits
Select commit
Hold shift + click to select a range
9274bb7
DeMorgan's Law
jerelmiller 922da17
Compare against no defer spec
jerelmiller 0bb58a0
Add new multipart mixed header
jerelmiller 9b63f24
Update request error message to suggest new format
jerelmiller 7a8292c
Add Alpha2 suffix to existing incremental types
jerelmiller 852a6a6
Add Alpha2 suffix to polyfill file
jerelmiller 8ac5c71
Add polyfill types for alpha9
jerelmiller 96112c0
Export alpha9 types
jerelmiller 56245aa
Remove ordering of incremental fields
jerelmiller 92fa99b
Add type for GraphQLResponseBody with alpha 9 format
jerelmiller fbfa0df
Update writeMultipartBody signature
jerelmiller c7abd87
Update payload type for willSendSubsequentPayload
jerelmiller 4d3beb0
Load from alpha 9
jerelmiller d6e19f6
Add alpha2 suffix to existing execute types and add alpha9 types
jerelmiller ddddd79
Update ApolloServer types
jerelmiller bb827ce
Update constructor types
jerelmiller 0da6d92
Ensure executeIncrementally returns alpha9 types
jerelmiller d8fa3ec
Handle formatting alpha9 errors
jerelmiller bd8d0c3
Throw if version mismatch from header
jerelmiller 1916a46
Simplify check
jerelmiller 5ec9b5e
Rename media types
jerelmiller 5aa7578
Change value of alpha9 spec version
jerelmiller 48e2572
Change output header depending on graphql version
jerelmiller c2403d5
Swap order of conditional
jerelmiller b7ce974
Enable incremental delivery tests for alpha9
jerelmiller 5c7bed1
Wrap existing tests in check for alpha2
jerelmiller 7df7889
Add back field ordering
jerelmiller 758f50f
Enable incremental delivery tests for alpha9
jerelmiller c6566c4
Reverse demorgan's
jerelmiller e34f911
Extract variable
jerelmiller 7b1f7af
Update test
jerelmiller 6437c0e
Fix condition
jerelmiller 14c9263
Combine conditionals
jerelmiller b3469ab
Use valid media type value for response
jerelmiller e486ca1
DeMorgan's law
jerelmiller c77e9f0
Fix incorrect header in test
jerelmiller ec029b0
Move test
jerelmiller c8932db
Fix typo
jerelmiller 016fbb9
Tweak error message
jerelmiller caada27
Use describe instead
jerelmiller 0610c85
Add tests for alpha.9
jerelmiller 7b8d287
Fix incorrect assertions for alpha.9
jerelmiller ecd31cb
Update test for alpha.9
jerelmiller fa0c4ee
Update another test to work with alpha.9
jerelmiller fc8c3a6
Update test in apolloServerTests for alpha.9
jerelmiller f5965e1
Update test description
jerelmiller 109c4a0
Fix incorrect assertion
jerelmiller 84862b9
Update smoke test for alpha.9
jerelmiller c0d24bd
Add basic tests for @stream
jerelmiller 756456a
Ordering
jerelmiller 80f06e9
Ensure tests are skipped instead of hidden
jerelmiller 5184e4c
Revert quotes
jerelmiller 586b102
Add changesets
jerelmiller 93534d0
Update docs
jerelmiller d865b57
Fix typo
jerelmiller 62e1cca
Add @yaacovcr/transform as optional peer dep
jerelmiller ef8da6c
Install transform in circle
jerelmiller 601cf6a
Add flag to load legacy incremental
jerelmiller 426026d
Remove check for graphql alpha.2
jerelmiller 45f35c1
Prefer alpha.9 format
jerelmiller ece5991
Don't error with incompatible graphql.js version
jerelmiller e8a6d0a
Remove checks for versions in tests
jerelmiller 6c005a7
Update error message
jerelmiller 01ac540
Track legacyExecute and executeIncrementally in separate vars
jerelmiller 6ffc9aa
Use legacy format when header used
jerelmiller 023425b
Update error snapshots
jerelmiller 18175de
Rename test descriptions
jerelmiller aff5045
Update apolloServerTests to remove check on version
jerelmiller b151633
Only run alpha.9 tests in circleci
jerelmiller 025d292
Update smoke test to check both versions
jerelmiller a17ffff
Fix ref in circle config
jerelmiller 1ad2066
Add ts-ignore
jerelmiller 6f1e3e6
Throw if old format requested but not supported
jerelmiller b7e1661
Install @yaacovcr/transform in prepare.sh
jerelmiller 0f8d32d
Add yaacovcr to cspell dict
jerelmiller 1d101dc
Fix typo
jerelmiller 13f005c
Update changeset
jerelmiller a7cbae6
Add another changeset
jerelmiller f697a2c
Update documentation
jerelmiller ef1938d
Fix typo
jerelmiller 18a9868
Use && instead of ||
jerelmiller fc889d8
Remove ordering on incremental fields
jerelmiller ce4d8d1
Allow v17.0.0-alpha.9
jerelmiller c9c8c78
Combine all changesets
jerelmiller 28e9d9c
Fix typo
jerelmiller b32394a
Grammar
jerelmiller 3c0a88e
Remove use of "modern" in changeset
jerelmiller bd5cd63
Revert changes to peer deps
jerelmiller 96af552
Don't export unneeded types
jerelmiller 5d15554
Update error messages
jerelmiller 79fb340
Update incrementalDeliverySpec header value
jerelmiller 77b57de
Fix typo
jerelmiller File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
--- | ||
'@apollo/server': minor | ||
--- | ||
|
||
Apollo Server now supports the modern incremental delivery protocol (`@defer` and `@stream`) that ships with `[email protected]`. To use the modern protocol, clients must send the `Accept` header with a value of `multipart/mixed; incrementalDeliverySpec=3283f8a`. | ||
|
||
To upgrade to 5.1 will depend on what version of `graphql` you have installed and whether you already support the incremental delivery protocol. | ||
|
||
## I use `graphql@16` without incremental delivery | ||
|
||
Continue using `graphql` v16 with no additional changes. Incremental delivery won't be available. | ||
|
||
## I use `graphql@16` but would like to add support for incremental delivery | ||
|
||
Install `[email protected]` and follow the ["Incremental delivery" guide](https://www.apollographql.com/docs/apollo-server/workflow/requests#incremental-delivery-experimental) to add the `@defer` and `@stream` directives to your schema. Clients should send the `Accept` header with a value of `multipart/mixed; incrementalDeliverySpec=3283f8a` to get multipart responses. | ||
|
||
## I use `[email protected]` and use incremental delivery | ||
|
||
You must upgrade to `[email protected]` to continue using incremental delivery. If you'd like to continue providing support for the legacy incremental protocol, install the [`@yaacovcr/transform`](https://github.com/yaacovCR/transform) package. Apollo Server will attempt to load this module when the client specifies an `Accept` header with a value of `multipart/mixed; deferSpec=20220824`. If this package is not installed, an error is returned by the server. | ||
|
||
Because Apollo Server now supports multiple versions of the incremental delivery types, the existing incremental delivery types have been renamed with an `Alpha2` suffix. If you import these types in your code, you will need to add the `Alpha2` suffix. | ||
|
||
```diff | ||
import type { | ||
- GraphQLExperimentalFormattedInitialIncrementalExecutionResult, | ||
+ GraphQLExperimentalFormattedInitialIncrementalExecutionResultAlpha2, | ||
|
||
- GraphQLExperimentalFormattedSubsequentIncrementalExecutionResult, | ||
+ GraphQLExperimentalFormattedSubsequentIncrementalExecutionResultAlpha2, | ||
|
||
- GraphQLExperimentalFormattedIncrementalResult, | ||
+ GraphQLExperimentalFormattedIncrementalResultAlpha2, | ||
|
||
- GraphQLExperimentalFormattedIncrementalDeferResult, | ||
+ GraphQLExperimentalFormattedIncrementalDeferResultAlpha2, | ||
|
||
- GraphQLExperimentalFormattedIncrementalStreamResult, | ||
+ GraphQLExperimentalFormattedIncrementalStreamResultAlpha2, | ||
} from '@apollo/server'; | ||
``` | ||
|
||
Incremental delivery types for the more modern `[email protected]` version are now available using the `Alpha9` suffix: | ||
|
||
```ts | ||
import type { | ||
GraphQLExperimentalFormattedInitialIncrementalExecutionResultAlpha9, | ||
GraphQLExperimentalFormattedSubsequentIncrementalExecutionResultAlpha9, | ||
GraphQLExperimentalFormattedIncrementalResultAlpha9, | ||
GraphQLExperimentalFormattedIncrementalDeferResultAlpha9, | ||
GraphQLExperimentalFormattedIncrementalStreamResultAlpha9, | ||
GraphQLExperimentalFormattedCompletedResultAlpha9, | ||
GraphQLExperimentalPendingResultAlpha9, | ||
} from '@apollo/server'; | ||
``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -221,4 +221,5 @@ whatwg | |
Wheelock's | ||
withrequired | ||
xorby | ||
yaacovcr | ||
YOURNAME |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -91,7 +91,7 @@ For more details, see [the CSRF prevention documentation](../security/cors#preve | |
|
||
## Incremental delivery (experimental) | ||
|
||
Incremental delivery is a [Stage 2: Draft Proposal](https://github.com/graphql/graphql-spec/pull/742) to the GraphQL specification which adds `@defer` and `@stream` executable directives. These directives allow clients to specify that parts of an operation can be sent after an initial response, so that slower fields do not delay all other fields. As of June 2025, the `graphql` library (also known as `graphql-js`) upon which Apollo Server is built implements incremental delivery only in the unreleased major version 17. If a pre-release of `[email protected].2` is installed in your server, Apollo Server can execute these incremental delivery directives and provide streaming [`multipart/mixed`](https://github.com/graphql/graphql-over-http/blob/main/rfcs/IncrementalDelivery.md) responses. | ||
Incremental delivery is a [Stage 1: Proposal](https://github.com/graphql/graphql-spec/pull/1110) to the GraphQL specification which adds `@defer` and `@stream` executable directives. These directives allow clients to specify that parts of an operation can be sent after an initial response, so that slower fields do not delay all other fields. As of June 2025, the `graphql` library (also known as `graphql-js`) upon which Apollo Server is built implements incremental delivery only in the unreleased major version 17. If a pre-release of `[email protected].9` is installed in your server, Apollo Server can execute these incremental delivery directives and provide streaming [`multipart/mixed`](https://github.com/graphql/graphql-over-http/blob/main/rfcs/IncrementalDelivery.md) responses. | ||
|
||
Support for incremental delivery in graphql version 17 is [opt-in](https://github.com/robrichard/defer-stream-wg/discussions/12), meaning the directives are not defined by default. In order to use `@defer` or `@stream`, you must provide the appropriate definition(s) in your SDL. The definitions below can be pasted into your schema as-is: | ||
|
||
|
@@ -119,8 +119,30 @@ const schema = new GraphQLSchema({ | |
}); | ||
``` | ||
|
||
Clients sending operations with incremental delivery directives need to explicitly indicate that they are expecting to receive `multipart/mixed` responses in an `accept` header. Moreover, because incremental delivery has not yet been finalized in the GraphQL spec and may change before the final version, they need to specify that they expect the particular response format that Apollo Server produces today via a `deferSpec` parameter. Specifically, clients prepared to accept incremental delivery responses should send an `accept` header like `multipart/mixed; deferSpec=20220824`. Note that this header implies that *only* multipart responses should be accepted; typically, clients will send an accept header like `multipart/mixed; deferSpec=20220824, application/json` indicating that either multipart or single-part responses are acceptable. | ||
Clients sending operations with incremental delivery directives need to explicitly indicate that they are expecting to receive `multipart/mixed` responses in an `accept` header. Moreover, because incremental delivery has not yet been finalized in the GraphQL spec and may change before the final version, they need to specify that they expect the particular response format that Apollo Server produces today via a `incrementalDeliverySpec` parameter. Specifically, clients prepared to accept incremental delivery responses should send an `accept` header like `multipart/mixed; incrementalDeliverySpec=3283f8a`. Note that this header implies that *only* multipart responses should be accepted; typically, clients will send an accept header like `multipart/mixed; incrementalDeliverySpec=3283f8a, application/json` indicating that either multipart or single-part responses are acceptable. | ||
|
||
> Apollo Server *only* supports the specific pre-release `[email protected].2`. Newer alpha versions of `graphql` v17 support a slightly different format for incremental delivery, which Apollo Server does not yet support. Apollo Server 5 checks the version of `graphql` you have installed and will not attempt to support incremental delivery unless it is precisely `17.0.0-alpha.2`. We hope to support the newer incremental delivery protocol in a future release, using a different `deferSpec` value. | ||
> Apollo Server *only* supports the specific pre-release `[email protected].9`. Apollo Server 5 checks the version of `graphql` you have installed and will not attempt to support incremental delivery unless it is precisely `17.0.0-alpha.9`. | ||
|
||
You cannot combine [batching](#batching) with incremental delivery in the same request. | ||
|
||
<Note> | ||
|
||
Apollo Server 5.1 changed the required pre-release `graphql` version from `17.0.0-alpha-2` to `17.0.0-alpha.9`. If you are using 5.0 or below, use `graphql` version `17.0.0-alpha.2` instead. | ||
jerelmiller marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
</Note> | ||
|
||
<MinVersion version="5.1.0"> | ||
|
||
### Add support for the legacy incremental delivery protocol | ||
|
||
</MinVersion> | ||
|
||
Clients may request the legacy incremental delivery protocol by specifying an `accept` header with a value of `multipart/mixed; deferSpec=20220824`. Apollo Server does not support the legacy incremental delivery protocol by default and an error will be returned to the client. | ||
|
||
You may choose to support the legacy incremental delivery protocol by installing the [`@yaacovcr/transform` package](https://github.com/yaacovCR/transform) which provides the needed utilities to format the incremental result using the legacy protocol. | ||
|
||
```sh | ||
npm install @yaacovcr/transform | ||
``` | ||
|
||
There is nothing else to configure. Apollo Server will load the necessary utility if this package is installed. |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if "modern" is an overly optimistic term to use throughout this PR. If we come up with a third protocol later, it won't age well. Would "current" work better than "modern"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is why I hate naming 😂. I just picked something to differentiate from it and the legacy version. I didn't really find a good name for the "now" version, but I'd be ok with "current" 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated in 3c0a88e
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the term is also used in errors?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, you're right! Updated in 5d15554