@@ -10,31 +10,74 @@ 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
+ The result of a GraphQL request must be either a single initial response or an
14
+ incremental stream. The response will be an incremental stream when the GraphQL
15
+ service has deferred or streamed data as a result of the ` @defer ` or ` @stream `
16
+ directives. When the result of the GraphQL operation is an incremental stream,
17
+ the first value will be an initial response, followed by one or more subsequent
18
+ responses.
19
+
20
+ ### Initial Response
21
+
22
+ An initial response must be a map.
14
23
15
24
If the request raised any errors, the response map must contain an entry with
16
25
key ` errors ` . The value of this entry is described in the "Errors" section. If
17
26
the request completed without raising any errors, this entry must not be
18
27
present.
19
28
20
- If the request included execution, the response map must contain an entry with
21
- key ` data ` . The value of this entry is described in the "Data" section. If the
22
- request failed before execution, due to a syntax error, missing information, or
23
- validation error, this entry must not be present.
29
+ If the request included execution, the initial response map must contain an
30
+ entry with key ` data ` . The value of this entry is described in the "Data"
31
+ section. If the request failed before execution, due to a syntax error, missing
32
+ information, or validation error, this entry must not be present.
33
+
34
+ When the result of the GraphQL operation is an incremental stream, the initial
35
+ response must contain an entry with key ` hasNext ` . The value of this entry must
36
+ be {true}. This entry must not be present for GraphQL operations that result in
37
+ a single initial response.
24
38
25
- The response map may also contain an entry with key ` extensions ` . This entry, if
26
- set, must have a map as its value. This entry is reserved for implementers to
27
- extend the protocol however they see fit, and hence there are no additional
28
- restrictions on its contents.
39
+ When the result of the GraphQL operation is an incremental stream, the initial
40
+ response may contain entries with the keys ` pending ` , ` incremental ` , and/or
41
+ ` completed ` . The value of these entries are described in the "Pending",
42
+ "Incremental", and "Completed" sections below.
43
+
44
+ The initial response map may also contain an entry with key ` extensions ` . This
45
+ entry, if set, must have a map as its value. This entry is reserved for
46
+ implementers to extend the protocol however they see fit, and hence there are no
47
+ additional restrictions on its contents.
29
48
30
49
To ensure future changes to the protocol do not break existing services and
31
- clients, the top level response map must not contain any entries other than the
32
- three described above.
50
+ clients, the initial response map must not contain any entries other than the
51
+ entries described above.
33
52
34
- Note: When ` errors ` is present in the response, it may be helpful for it to
35
- appear first when serialized to make it more clear when errors are present in a
53
+ Note: When ` errors ` is present in a response, it may be helpful for it to appear
54
+ first when serialized to make it more clear when errors are present in a
36
55
response during debugging.
37
56
57
+ ### Subsequent Response
58
+
59
+ When the result of the GraphQL operation is an incremental stream, the first
60
+ value will be an initial response, followed by one or more subsequent responses.
61
+ A subsequent response must be a map.
62
+
63
+ Each subsequent response must contain an entry with key ` hasNext ` . The value of
64
+ this entry must be {true} for all but the last response in the stream. The value
65
+ of this entry must be {false} for the last response of the stream.
66
+
67
+ Each subsequent response may contain entries with the keys ` pending ` ,
68
+ ` incremental ` , and/or ` completed ` . The value of these entries are described in
69
+ the "Pending", "Incremental", and "Completed" sections below.
70
+
71
+ The subsequent response map may also contain an entry with key ` extensions ` .
72
+ This entry, if set, must have a map as its value. This entry is reserved for
73
+ implementers to extend the protocol however they see fit, and hence there are no
74
+ additional restrictions on its contents. Implementers may send subsequent
75
+ responses containing only ` hasNext ` and ` extensions ` entries.
76
+
77
+ To ensure future changes to the protocol do not break existing services and
78
+ clients, the initial response map must not contain any entries other than the
79
+ entries described above.
80
+
38
81
### Data
39
82
40
83
The ` data ` entry in the response will be the result of the execution of the
@@ -48,6 +91,10 @@ present in the response.
48
91
If an error was raised during the execution that prevented a valid response, the
49
92
` data ` entry in the response should be ` null ` .
50
93
94
+ When the response of the GraphQL operation is an incremental stream, ` data ` may
95
+ only be present in the initial response. ` data ` must not be present in any
96
+ subsequent responses.
97
+
51
98
### Errors
52
99
53
100
The ` errors ` entry in the response is a non-empty list of errors raised during
@@ -107,14 +154,8 @@ syntax element.
107
154
If an error can be associated to a particular field in the GraphQL result, it
108
155
must contain an entry with the key ` path ` that details the path of the response
109
156
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.
157
+ ` null ` result is intentional or caused by a runtime error. The value of this
158
+ field is described in the [ Path] ( #sec-Path ) section.
118
159
119
160
For example, if fetching one of the friends' names fails in the following
120
161
operation:
@@ -244,6 +285,173 @@ discouraged.
244
285
}
245
286
```
246
287
288
+ ### Path
289
+
290
+ A ` path ` field allows for the association to a particular field in a GraphQL
291
+ result. This field should be a list of path segments starting at the root of the
292
+ response and ending with the field to be associated with. Path segments that
293
+ represent fields should be strings, and path segments that represent list
294
+ indices should be 0-indexed integers. If the path is associated to an aliased
295
+ field, the path should use the aliased name, since it represents a path in the
296
+ response, not in the request.
297
+
298
+ When the ` path ` field is present on an "Error result", it indicates the response
299
+ field which experienced the error.
300
+
301
+ ### Pending
302
+
303
+ The ` pending ` entry in the response is a non-empty list of Pending Results. If
304
+ the response of the GraphQL operation is an incremental stream, this field may
305
+ appear on both the initial and subsequent responses. If present, the ` pending `
306
+ entry must contain at least one Pending Result.
307
+
308
+ Each Pending Result corresponds to either a ` @defer ` or ` @stream ` directive
309
+ located at a specific path in the response data. The Pending Result is used to
310
+ communicate that the GraphQL service has chosen to incrementally deliver the
311
+ data associated with this ` @defer ` or ` @stream ` directive and clients should
312
+ expect the associated data in either the current response, or one of the
313
+ following responses.
314
+
315
+ ** Pending Result Format**
316
+
317
+ Every Pending Result must contain an entry with the key ` id ` with a string
318
+ value. This ` id ` should be used by clients to correlate Pending Results with
319
+ Completed Results. The ` id ` value must be unique for the entire response stream.
320
+ There must not be any other Pending Result in any response that contains the
321
+ same ` id ` .
322
+
323
+ Every Pending Result must contain an entry with the key ` path ` . When the Pending
324
+ Result is associated with a ` @stream ` directive, it indicates the response list
325
+ field that is not known to be complete. Clients should expect the GraphQL
326
+ Service to incrementally deliver the remainder of indicated list field. When the
327
+ Pending Result is associated with a ` @defer ` directive, it indicates that the
328
+ response fields contained in the deferred fragment are not known to be complete.
329
+ Clients should expect the GraphQL Service to incrementally deliver the remainder
330
+ of the fields contained in the deferred fragment.
331
+
332
+ If the associated ` @defer ` or ` @stream ` directive contains a ` label ` argument,
333
+ the Pending Result must contain an entry ` label ` with the value of this
334
+ argument.
335
+
336
+ If a Pending Result is not returned for a ` @defer ` or ` @stream ` directive,
337
+ clients must assume that the GraphQL service chose not to incrementally deliver
338
+ this data, and the data can be found either in the ` data ` entry in the initial
339
+ response, or one of the Incremental Results in a prior subsequent response.
340
+
341
+ ### Incremental
342
+
343
+ The ` incremental ` entry in the response is a non-empty list of Incremental
344
+ Results. If the response of the GraphQL operation is an incremental stream, this
345
+ field may appear on both the initial and subsequent responses. If present, the
346
+ ` incremental ` entry must contain at least one Incremental Result.
347
+
348
+ The Incremental Result is used to deliver data that the GraphQL service has
349
+ chosen to incrementally deliver. An Incremental Result may be ether an
350
+ Incremental List Result or an Incremental Object Result.
351
+
352
+ An Incremental List Result is used to deliver additional list items for a list
353
+ field with a ` @stream ` directive.
354
+
355
+ An Incremental Object Result is used to deliver additional response fields that
356
+ were contained in one or more fragments with a ` @defer ` directive.
357
+
358
+ ** Incremental Result Format**
359
+
360
+ Every Incremental Result must contain an entry with the key ` id ` with a string
361
+ value. This ` id ` must match the ` id ` that was returned in a prior Pending
362
+ Result.
363
+
364
+ Additionally, Incremental List Results and Incremental Object Results have
365
+ further requirements.
366
+
367
+ ** Incremental List Result Format**
368
+
369
+ An Incremental List Result's ` id ` entry must match the ` id ` that was returned in
370
+ a prior Pending Result. This Pending Result must be associated with a ` @stream `
371
+ directive.
372
+
373
+ The Incremental List Result's path can be determined using the prior Pending
374
+ Result with the same ` id ` as this Incremental Result. The Incremental List
375
+ Result's path is the same as the Pending Result's ` path ` .
376
+
377
+ Every Incremental List Result must contain an ` items ` entry. The ` items ` entry
378
+ must contain a list of additional list items for the response field at the
379
+ Incremental List Result's ` path ` . This output will be a list of the same type of
380
+ the response field at this path.
381
+
382
+ If any field errors were raised during the execution of the results in ` items `
383
+ and these errors propagate to a path higher than the Incremental List Result's
384
+ path, The Incremental List Result is considered failed and should not be
385
+ included in the response stream. The errors that caused this failure will be
386
+ included in a Completed Result.
387
+
388
+ If any field errors were raised during the execution of the results in ` items `
389
+ and these errors did not propagate to a path higher than the Incremental List
390
+ Result's path, the Incremental List Result must contain an entry with key
391
+ ` errors ` containing these field errors. The value of this entry is described in
392
+ the "Errors" section.
393
+
394
+ ** Incremental Object Result Format**
395
+
396
+ An Incremental Object Result's ` id ` entry must match the ` id ` that was returned
397
+ in a prior Pending Result. This Pending Result must be associated with a
398
+ ` @defer ` directive.
399
+
400
+ The Incremental Object Result's path can be determined using the prior Pending
401
+ Result with the same ` id ` as this Incremental Result. The Incremental Object
402
+ Result may contain a ` subPath ` entry. If the ` subPath ` entry is present, The
403
+ Incremental Object Result's path can be determined by concatenating the Pending
404
+ Result's ` path ` with this ` subPath ` . If no ` subPath ` entry is present, the path
405
+ is the same as the Pending Result's ` path ` .
406
+
407
+ Every Incremental Object Result must contain a ` data ` entry. The ` data ` entry
408
+ must contain a map of additional response fields. The ` data ` entry in an
409
+ Incremental Object Result will be of the type of a particular field in the
410
+ GraphQL result. The Incremental Object Result's path will contain the path
411
+ segments of the field this data is associated with.
412
+
413
+ An Incremental Object Result's data may contain response fields that were
414
+ contained in more than one deferred fragments. In that case, the ` id ` of the
415
+ Incremental Object Result must point to the Pending Result that results in the
416
+ shortest path.
417
+
418
+ If any field errors were raised during the execution of the results in ` data `
419
+ and these errors propagated to a path higher than the Incremental Object
420
+ Result's path, The Incremental Object Result is considered failed and should not
421
+ be included in the response stream. The errors that caused this failure will be
422
+ included in a Completed Result.
423
+
424
+ If any field errors were raised during the execution of the results in ` data `
425
+ and these errors did not propagate to a path higher than the Incremental Object
426
+ Result's path, the Incremental Object Result must contain an entry with key
427
+ ` errors ` containing these field errors. The value of this entry is described in
428
+ the "Errors" section.
429
+
430
+ ### Completed
431
+
432
+ The ` completed ` entry in the response is a non-empty list of Completed Results.
433
+ If the response of the GraphQL operation is an incremental stream, this field
434
+ may appear on both the initial and subsequent responses. If present, the
435
+ ` completed ` entry must contain at least one Completed Result.
436
+
437
+ Each Completed Result corresponds to a prior Pending Result. The Completed
438
+ Result is used to communicate that the GraphQL service has completed the
439
+ incremental delivery of the data associated with the corresponding Pending
440
+ Result. The associated data must have been completed in the current response.
441
+
442
+ ** Completed Result Format**
443
+
444
+ Every Completed Result must contain an entry with the key ` id ` with a string
445
+ value. The ` id ` entry must match the ` id ` that was returned in a prior Pending
446
+ Result.
447
+
448
+ A Completed Result may contain an ` errors ` entry. When the ` errors ` entry is
449
+ present, it informs clients that the delivery of the data associated with the
450
+ corresponding Pending Result has failed, due to an error bubbling to a path
451
+ higher than the Incremental Data Result's path. The ` errors ` entry must contain
452
+ these field errors. The value of this entry is described in the "Errors"
453
+ section.
454
+
247
455
## Serialization Format
248
456
249
457
GraphQL does not require a specific serialization format. However, clients
0 commit comments