Skip to content

Commit 6734003

Browse files
committed
Spec edits for incremental delivery, Section 3 & 7 only
1 parent 7073e3a commit 6734003

File tree

2 files changed

+495
-13
lines changed

2 files changed

+495
-13
lines changed

spec/Section 3 -- Type System.md

+104-2
Original file line numberDiff line numberDiff line change
@@ -794,8 +794,9 @@ And will yield the subset of each object type queried:
794794
When querying an Object, the resulting mapping of fields are conceptually
795795
ordered in the same order in which they were encountered during execution,
796796
excluding fragments for which the type does not apply and fields or fragments
797-
that are skipped via `@skip` or `@include` directives. This ordering is
798-
correctly produced when using the {CollectFields()} algorithm.
797+
that are skipped via `@skip` or `@include` directives or temporarily skipped via
798+
`@defer`. This ordering is correctly produced when using the {CollectFields()}
799+
algorithm.
799800

800801
Response serialization formats capable of representing ordered maps should
801802
maintain this ordering. Serialization formats which can only represent unordered
@@ -1942,6 +1943,11 @@ by a validator, executor, or client tool such as a code generator.
19421943

19431944
GraphQL implementations should provide the `@skip` and `@include` directives.
19441945

1946+
GraphQL implementations are not required to implement the `@defer` and `@stream`
1947+
directives. If either or both of these directives are implemented, they must be
1948+
implemented according to this specification. GraphQL implementations that do not
1949+
support these directives must not make them available via introspection.
1950+
19451951
GraphQL implementations that support the type system definition language must
19461952
provide the `@deprecated` directive if representing deprecated portions of the
19471953
schema.
@@ -2162,3 +2168,99 @@ to the relevant IETF specification.
21622168
```graphql example
21632169
scalar UUID @specifiedBy(url: "https://tools.ietf.org/html/rfc4122")
21642170
```
2171+
2172+
### @defer
2173+
2174+
```graphql
2175+
directive @defer(
2176+
label: String
2177+
if: Boolean! = true
2178+
) on FRAGMENT_SPREAD | INLINE_FRAGMENT
2179+
```
2180+
2181+
The `@defer` directive may be provided for fragment spreads and inline fragments
2182+
to inform the executor to delay the execution of the current fragment to
2183+
indicate deprioritization of the current fragment. A query with `@defer`
2184+
directive will cause the request to potentially return multiple responses, where
2185+
non-deferred data is delivered in the initial response and data deferred is
2186+
delivered in a subsequent response. `@include` and `@skip` take precedence over
2187+
`@defer`.
2188+
2189+
```graphql example
2190+
query myQuery($shouldDefer: Boolean) {
2191+
user {
2192+
name
2193+
...someFragment @defer(label: "someLabel", if: $shouldDefer)
2194+
}
2195+
}
2196+
fragment someFragment on User {
2197+
id
2198+
profile_picture {
2199+
uri
2200+
}
2201+
}
2202+
```
2203+
2204+
#### @defer Arguments
2205+
2206+
- `if: Boolean! = true` - When `true`, fragment _should_ be deferred (see
2207+
related note below). When `false`, fragment will not be deferred and data will
2208+
be included in the initial response. Defaults to `true` when omitted.
2209+
- `label: String` - May be used by GraphQL clients to identify the data from
2210+
responses and associate it with the corresponding defer directive. If
2211+
provided, the GraphQL service must add it to the corresponding pending object
2212+
in the response. `label` must be unique label across all `@defer` and
2213+
`@stream` directives in a document. `label` must not be provided as a
2214+
variable.
2215+
2216+
### @stream
2217+
2218+
```graphql
2219+
directive @stream(
2220+
label: String
2221+
if: Boolean! = true
2222+
initialCount: Int = 0
2223+
) on FIELD
2224+
```
2225+
2226+
The `@stream` directive may be provided for a field of `List` type so that the
2227+
backend can leverage technology such as asynchronous iterators to provide a
2228+
partial list in the initial response, and additional list items in subsequent
2229+
responses. `@include` and `@skip` take precedence over `@stream`.
2230+
2231+
```graphql example
2232+
query myQuery($shouldStream: Boolean) {
2233+
user {
2234+
friends(first: 10) {
2235+
nodes @stream(label: "friendsStream", initialCount: 5, if: $shouldStream)
2236+
}
2237+
}
2238+
}
2239+
```
2240+
2241+
#### @stream Arguments
2242+
2243+
- `if: Boolean! = true` - When `true`, field _should_ be streamed (see related
2244+
note below). When `false`, the field will not be streamed and all list items
2245+
will be included in the initial response. Defaults to `true` when omitted.
2246+
- `label: String` - May be used by GraphQL clients to identify the data from
2247+
responses and associate it with the corresponding stream directive. If
2248+
provided, the GraphQL service must add it to the corresponding pending object
2249+
in the response. `label` must be unique label across all `@defer` and
2250+
`@stream` directives in a document. `label` must not be provided as a
2251+
variable.
2252+
- `initialCount: Int` - The number of list items the service should return as
2253+
part of the initial response. If omitted, defaults to `0`. A field error will
2254+
be raised if the value of this argument is less than `0`.
2255+
2256+
Note: The ability to defer and/or stream parts of a response can have a
2257+
potentially significant impact on application performance. Developers generally
2258+
need clear, predictable control over their application's performance. It is
2259+
highly recommended that GraphQL services honor the `@defer` and `@stream`
2260+
directives on each execution. However, the specification allows advanced use
2261+
cases where the service can determine that it is more performant to not defer
2262+
and/or stream. Therefore, GraphQL clients _must_ be able to process a response
2263+
that ignores the `@defer` and/or `@stream` directives. This also applies to the
2264+
`initialCount` argument on the `@stream` directive. Clients _must_ be able to
2265+
process a streamed response that contains a different number of initial list
2266+
items than what was specified in the `initialCount` argument.

0 commit comments

Comments
 (0)