@@ -10,7 +10,12 @@ the case that any _field error_ was raised on a field and was replaced with
10
10
11
11
## Response Format
12
12
13
- A response to a GraphQL request must be a map.
13
+ A response to a GraphQL request must be a map or a stream of incrementally
14
+ delivered results. The response will be a stream of incrementally delivered
15
+ results when the GraphQL service has deferred or streamed data as a result of
16
+ the ` @defer ` or ` @stream ` directives. When the response of the GraphQL operation
17
+ contains incrementally delivered results, the first value will be an initial
18
+ payload, followed by one or more subsequent payloads.
14
19
15
20
If the request raised any errors, the response map must contain an entry with
16
21
key ` errors ` . The value of this entry is described in the "Errors" section. If
@@ -22,14 +27,31 @@ key `data`. The value of this entry is described in the "Data" section. If the
22
27
request failed before execution, due to a syntax error, missing information, or
23
28
validation error, this entry must not be present.
24
29
30
+ When the response of the GraphQL operation contains incrementally delivered
31
+ results, both the initial payload and all subsequent payloads must contain an
32
+ entry with key ` hasNext ` . The value of this entry must be {true} for all but the
33
+ last response in the stream. The value of this entry must be {false} for the
34
+ last response of the stream. This entry must not be present for GraphQL
35
+ operations that return a single response map.
36
+
37
+ When the response of the GraphQL operation contains incrementally delivered
38
+ results, both the initial payload and any subsequent payloads may contain
39
+ entries with the keys ` pending ` , ` incremental ` , and/or ` completed ` . The value of
40
+ these entries are described in the "Pending", "Incremental", and "Completed"
41
+ sections below.
42
+
25
43
The response map may also contain an entry with key ` extensions ` . This entry, if
26
44
set, must have a map as its value. This entry is reserved for implementers to
27
45
extend the protocol however they see fit, and hence there are no additional
28
- restrictions on its contents.
46
+ restrictions on its contents. When the response of the GraphQL operation is a
47
+ response stream, the initial payload and any subsequent payloads may contain an
48
+ entry with the key ` extensions ` , also reserved for implementers to extend the
49
+ protocol however they see fit. Additionally, implementers may send subsequent
50
+ payloads containing only ` hasNext ` and ` extensions ` entries.
29
51
30
52
To ensure future changes to the protocol do not break existing services and
31
53
clients, the top level response map must not contain any entries other than the
32
- three described above.
54
+ entries described above.
33
55
34
56
Note: When ` errors ` is present in the response, it may be helpful for it to
35
57
appear first when serialized to make it more clear when errors are present in a
@@ -48,6 +70,10 @@ present in the result.
48
70
If an error was raised during the execution that prevented a valid response, the
49
71
` data ` entry in the response should be ` null ` .
50
72
73
+ When the response of the GraphQL operation contains incrementally delivered
74
+ results, ` data ` may only be present in the initial payload. ` data ` must not be
75
+ present in any subsequent payloads.
76
+
51
77
### Errors
52
78
53
79
The ` errors ` entry in the response is a non-empty list of errors raised during
@@ -107,14 +133,8 @@ syntax element.
107
133
If an error can be associated to a particular field in the GraphQL result, it
108
134
must contain an entry with the key ` path ` that details the path of the response
109
135
field which experienced the error. This allows clients to identify whether a
110
- ` null ` result is intentional or caused by a runtime error.
111
-
112
- If present, this field must be a list of path segments starting at the root of
113
- the response and ending with the field associated with the error. Path segments
114
- that represent fields must be strings, and path segments that represent list
115
- indices must be 0-indexed integers. If the error happens in an aliased field,
116
- the path to the error must use the aliased name, since it represents a path in
117
- the response, not in the request.
136
+ ` null ` result is intentional or caused by a runtime error. The value of this
137
+ field is described in the [ Path] ( #sec-Path ) section.
118
138
119
139
For example, if fetching one of the friends' names fails in the following
120
140
operation:
@@ -244,6 +264,170 @@ discouraged.
244
264
}
245
265
```
246
266
267
+ ### Path
268
+
269
+ A ` path ` field allows for the association to a particular field in a GraphQL
270
+ result. This field should be a list of path segments starting at the root of the
271
+ response and ending with the field to be associated with. Path segments that
272
+ represent fields should be strings, and path segments that represent list
273
+ indices should be 0-indexed integers. If the path is associated to an aliased
274
+ field, the path should use the aliased name, since it represents a path in the
275
+ response, not in the request.
276
+
277
+ When the ` path ` field is present on an "Error result", it indicates the response
278
+ field which experienced the error.
279
+
280
+ ### Pending
281
+
282
+ The ` pending ` entry in the response is a non-empty list of Pending Results. If
283
+ the response of the GraphQL operation contains incrementally delivered results,
284
+ this field may appear on both the initial and subsequent payloads. If present,
285
+ the ` pending ` entry must contain at least one Pending Result.
286
+
287
+ Each Pending Result corresponds to either a ` @defer ` or ` @stream ` directive
288
+ located at a specific path in the response data. The Pending Result is used to
289
+ communicate that the GraphQL service has chosen to incrementally deliver the
290
+ data associated with this ` @defer ` or ` @stream ` directive and clients should
291
+ expect the associated data in either the current payload, or one of the
292
+ following payloads.
293
+
294
+ ** Pending Result Format**
295
+
296
+ Every Pending Result must contain an entry with the key ` id ` with a string
297
+ value. This ` id ` should be used by clients to correlate Pending Results with
298
+ Completed Results. The ` id ` value must be unique for the entire response stream.
299
+ There must not be any other Pending Result in any payload that contains the same
300
+ ` id ` .
301
+
302
+ Every Pending Result must contain an entry with the key ` path ` . When the Pending
303
+ Result is associated with a ` @stream ` directive, it indicates the response list
304
+ field that is not known to be complete. Clients should expect the GraphQL
305
+ Service to incrementally deliver the remainder of indicated list field. When the
306
+ Pending Result is associated with a ` @defer ` directive, it indicates that the
307
+ response fields contained in the deferred fragment are not known to be complete.
308
+ Clients should expect the the GraphQL Service to incrementally deliver the
309
+ remainder of the fields contained in the deferred fragment.
310
+
311
+ If a Pending Result is not returned for a ` @defer ` or ` @stream ` directive,
312
+ clients must assume that the GraphQL service chose not to incrementally deliver
313
+ this data, and the data can be found either in the ` data ` entry in the initial
314
+ payload, or one of the Incremental Results in a prior payload.
315
+
316
+ ### Incremental
317
+
318
+ The ` incremental ` entry in the response is a non-empty list of Incremental
319
+ Results. If the response of the GraphQL operation contains incrementally
320
+ delivered results, this field may appear on both the initial and subsequent
321
+ values. If present, the ` incremental ` entry must contain at least one
322
+ Incremental Result.
323
+
324
+ The Incremental Result is used to deliver data that the GraphQL service has
325
+ chosen to incrementally deliver. An Incremental Result may be ether an
326
+ Incremental List Result or an Incremental Object Result.
327
+
328
+ An Incremental List Result is used to deliver additional list items for a list
329
+ field with a ` @stream ` directive.
330
+
331
+ An Incremental Object Result is used to deliver additional response fields that
332
+ were contained in one or more fragments with a ` @defer ` directive.
333
+
334
+ ** Incremental Result Format**
335
+
336
+ Every Incremental Result must contain an entry with the key ` id ` with a string
337
+ value. This ` id ` must match the ` id ` that was returned in a prior Pending
338
+ Result.
339
+
340
+ Additionally, Incremental List Results and Incremental Object Results have
341
+ further requirements.
342
+
343
+ ** Incremental List Result Format**
344
+
345
+ An Incremental List Result's ` id ` entry must match the ` id ` that was returned in
346
+ a prior Pending Result. This Pending Result must be associated with a ` @stream `
347
+ directive.
348
+
349
+ The Incremental List Result's ` path ` can be determined using the prior Pending
350
+ Result with the same ` id ` as this Incremental Result. The Incremental List
351
+ Result's ` path ` is the same as the Pending Result's ` path ` .
352
+
353
+ Every Incremental List Result must contain an ` items ` entry. The ` items ` entry
354
+ must contain a list of additional list items for the response field at the
355
+ Incremental List Result's ` path ` . This output will be a list of the same type of
356
+ the response field at this path.
357
+
358
+ If any field errors were raised during the execution of the results in ` items `
359
+ and these errors bubbled to a path higher than the Incremental List Result's
360
+ path, The Incremental List Result is considered failed and should not be
361
+ included in the response stream. The errors that caused this failure will be
362
+ included in a Completed Result.
363
+
364
+ If any field errors were raised during the execution of the results in ` items `
365
+ and these errors did not bubble to a path higher than the Incremental List
366
+ Result's path, the Incremental List Result must contain an entry with key
367
+ ` errors ` containing these field errors. The value of this entry is described in
368
+ the "Errors" section.
369
+
370
+ ** Incremental Object Result Format**
371
+
372
+ An Incremental List Result's ` id ` entry must match the ` id ` that was returned in
373
+ a prior Pending Result. This Pending Result must be associated with a ` @defer `
374
+ directive.
375
+
376
+ The Incremental Object Result's ` path ` can be determined using the prior Pending
377
+ Result with the same ` id ` as this Incremental Result. The Incremental Object
378
+ Result may contain a ` subPath ` entry. If the ` subPath ` entry is present, The
379
+ Incremental Object Record's path can be determined by concatenating the Pending
380
+ Result's ` path ` with this ` subPath ` . If no ` subPath ` entry is present, the path
381
+ is the same as the Pending Result's ` path ` .
382
+
383
+ Every Incremental Object Result must contain an ` data ` entry. The ` data ` entry
384
+ must contain a map of additional response fields. The ` data ` entry in an
385
+ Incremental Object Result will be of the type of a particular field in the
386
+ GraphQL result. The Incremental Object Result's ` path ` will contain the path
387
+ segments of the field this data is associated with.
388
+
389
+ An Incremental Object Result's data may contain response fields that were
390
+ contained in more than one deferred fragments. In that case, the ` id ` of the
391
+ Incremental Object Result must point to the Pending Result that results in the
392
+ shortest ` subPath ` .
393
+
394
+ If any field errors were raised during the execution of the results in ` data `
395
+ and these errors bubbled to a path higher than the Incremental Object Result's
396
+ path, The Incremental Object Result is considered failed and should not be
397
+ included in the response stream. The errors that caused this failure will be
398
+ included in a Completed Result.
399
+
400
+ If any field errors were raised during the execution of the results in ` data `
401
+ and these errors did not bubble to a path higher than the Incremental Object
402
+ Result's path, the Incremental Object Result must contain an entry with key
403
+ ` errors ` containing these field errors. The value of this entry is described in
404
+ the "Errors" section.
405
+
406
+ ### Completed
407
+
408
+ The ` completed ` entry in the response is a non-empty list of Completed Results.
409
+ If the response of the GraphQL operation contains incrementally delivered
410
+ results, this field may appear on both the initial and subsequent payloads. If
411
+ present, the ` completed ` entry must contain at least one Completed Result.
412
+
413
+ Each Completed Result corresponds to a prior Pending Result. The Completed
414
+ Result is used to communicate that the GraphQL service has completed the
415
+ incremental delivery of the data associated with the corresponding Pending
416
+ Result. The associated data must have been completed in the current payload.
417
+
418
+ ** Completed Result Format**
419
+
420
+ Every Completed Result must contain an entry with the key ` id ` with a string
421
+ value. The ` id ` entry must match the ` id ` that was returned in a prior Pending
422
+ Result.
423
+
424
+ A Completed Result may contain an ` errors ` entry. When the ` errors ` entry is
425
+ present, it informs clients that the delivery of the data associated with the
426
+ corresponding Pending Result has failed, due to an error bubbling to a path
427
+ higher than the Incremental Data Result's path. The ` errors ` entry must contain
428
+ these field errors. The value of this entry is described in the "Errors"
429
+ section.e
430
+
247
431
## Serialization Format
248
432
249
433
GraphQL does not require a specific serialization format. However, clients
0 commit comments