Skip to content

Commit 2f36b5e

Browse files
committed
Spec edits for incremental delivery, Section 3
1 parent 2073bc8 commit 2f36b5e

File tree

1 file changed

+111
-2
lines changed

1 file changed

+111
-2
lines changed

spec/Section 3 -- Type System.md

+111-2
Original file line numberDiff line numberDiff line change
@@ -794,8 +794,8 @@ 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 postponed via `@defer`.
798+
This ordering is correctly produced when using the {CollectFields()} algorithm.
799799

800800
Response serialization formats capable of representing ordered maps should
801801
maintain this ordering. Serialization formats which can only represent unordered
@@ -1948,6 +1948,14 @@ GraphQL implementations that support the type system definition language must
19481948
provide the `@deprecated` directive if representing deprecated portions of the
19491949
schema.
19501950

1951+
GraphQL implementations may provide the `@defer` and/or `@stream` directives. If
1952+
either or both of these directives are provided, they must conform to the
1953+
requirements defined in this specification.
1954+
1955+
Note: The [Directives Are Defined](#sec-Directives-Are-Defined) validation rule
1956+
ensures that GraphQL Operations containing the `@defer` or `@stream` directives
1957+
cannot be executed by a GraphQL service that does not support them.
1958+
19511959
GraphQL implementations that support the type system definition language should
19521960
provide the `@specifiedBy` directive if representing custom scalar definitions.
19531961

@@ -2164,3 +2172,104 @@ to the relevant IETF specification.
21642172
```graphql example
21652173
scalar UUID @specifiedBy(url: "https://tools.ietf.org/html/rfc4122")
21662174
```
2175+
2176+
### @defer
2177+
2178+
```graphql
2179+
directive @defer(
2180+
label: String
2181+
if: Boolean! = true
2182+
) on FRAGMENT_SPREAD | INLINE_FRAGMENT
2183+
```
2184+
2185+
The `@defer` directive may be provided on a fragment spread or inline fragment
2186+
to indicate that execution of the related selection set should be deferred. When
2187+
a request includes the `@defer` directive, the result may consist of multiple
2188+
responses: the initial response containing all non-deferred data, while
2189+
subsequent responses include deferred data.
2190+
2191+
The `@include` and `@skip` directives take precedence over `@defer`.
2192+
2193+
```graphql example
2194+
query myQuery($shouldDefer: Boolean! = true) {
2195+
user {
2196+
name
2197+
...someFragment @defer(label: "someLabel", if: $shouldDefer)
2198+
}
2199+
}
2200+
fragment someFragment on User {
2201+
id
2202+
profile_picture {
2203+
uri
2204+
}
2205+
}
2206+
```
2207+
2208+
#### @defer Arguments
2209+
2210+
- `if: Boolean! = true` - When `true`, fragment _should_ be deferred (see
2211+
related note below). When `false`, fragment must not be deferred. Defaults to
2212+
`true` when omitted.
2213+
- `label: String` - An optional string literal (variables are disallowed) used
2214+
by GraphQL clients to identify data from responses and associate it with the
2215+
corresponding defer directive. If provided, the GraphQL service must include
2216+
this label in the corresponding pending object within the response. The
2217+
`label` argument must be unique across all `@defer` and `@stream` directives
2218+
in the document.
2219+
2220+
### @stream
2221+
2222+
```graphql
2223+
directive @stream(
2224+
label: String
2225+
if: Boolean! = true
2226+
initialCount: Int = 0
2227+
) on FIELD
2228+
```
2229+
2230+
The `@stream` directive may be provided for a field whose type incorporates a
2231+
`List` type modifier; the directive enables the backend to leverage technology
2232+
such as asynchronous iterators to provide a partial list initially, and
2233+
additional list items in subsequent responses.
2234+
2235+
The `@include` and `@skip` directives take precedence over `@stream`.
2236+
2237+
```graphql example
2238+
query myQuery($shouldStream: Boolean! = true) {
2239+
user {
2240+
friends(first: 10) {
2241+
nodes
2242+
@stream(label: "friendsStream", initialCount: 5, if: $shouldStream) {
2243+
name
2244+
}
2245+
}
2246+
}
2247+
}
2248+
```
2249+
2250+
#### @stream Arguments
2251+
2252+
- `if: Boolean! = true` - When `true`, field _should_ be streamed (see related
2253+
note below). When `false`, the field must not be streamed and all list items
2254+
must be initially included. Defaults to `true` when omitted.
2255+
- `label: String` - An optional string literal (variables are disallowed) used
2256+
by GraphQL clients to identify data from responses and associate it with the
2257+
corresponding stream directive. If provided, the GraphQL service must include
2258+
this label in the corresponding pending object within the result. The `label`
2259+
argument must be unique across all `@defer` and `@stream` directives in the
2260+
document.
2261+
- `initialCount: Int` - The number of list items the service should return
2262+
initially. If omitted, defaults to `0`. A field error will be raised if the
2263+
value of this argument is less than `0`.
2264+
2265+
Note: The ability to defer and/or stream parts of a response can have a
2266+
potentially significant impact on application performance. Developers generally
2267+
need clear, predictable control over their application's performance. It is
2268+
highly recommended that GraphQL services honor the `@defer` and `@stream`
2269+
directives on each execution. However, the specification allows advanced use
2270+
cases where the service can determine that it is more performant to not defer
2271+
and/or stream. Therefore, GraphQL clients _must_ be able to process a response
2272+
that ignores the `@defer` and/or `@stream` directives. This also applies to the
2273+
`initialCount` argument on the `@stream` directive. Clients _must_ be able to
2274+
process a streamed response that contains a different number of initial list
2275+
items than what was specified in the `initialCount` argument.

0 commit comments

Comments
 (0)