Skip to content

Commit 6e1ef1f

Browse files
committed
Spec edits for incremental delivery, Section 7 only
1 parent 65d0abe commit 6e1ef1f

File tree

1 file changed

+217
-15
lines changed

1 file changed

+217
-15
lines changed

spec/Section 7 -- Response.md

Lines changed: 217 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,31 +10,74 @@ the case that any _field error_ was raised on a field and was replaced with
1010

1111
## Response Format
1212

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.
1423

1524
If the request raised any errors, the response map must contain an entry with
1625
key `errors`. The value of this entry is described in the "Errors" section. If
1726
the request completed without raising any errors, this entry must not be
1827
present.
1928

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.
38+
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.
2443

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.
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.
2948

3049
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.
3352

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
3655
response during debugging.
3756

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+
3881
### Data
3982

4083
The `data` entry in the response will be the result of the execution of the
@@ -48,6 +91,10 @@ present in the response.
4891
If an error was raised during the execution that prevented a valid response, the
4992
`data` entry in the response should be `null`.
5093

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+
5198
### Errors
5299

53100
The `errors` entry in the response is a non-empty list of errors raised during
@@ -240,8 +287,9 @@ discouraged.
240287

241288
### Path
242289

243-
:: A _path entry_ is an entry within an _error result_ that allows for
244-
association with a particular field reached during GraphQL execution.
290+
:: A _path entry_ is an entry within an _error result_ or a _pending result_
291+
that allows for association with a particular field reached during GraphQL
292+
execution.
245293

246294
The value for a _path entry_ must be a list of path segments starting at the
247295
root of the response and ending with the field to be associated with. Path
@@ -253,6 +301,160 @@ response, not in the request.
253301
When the _path entry_ is present on an _error result_, it identifies the
254302
response field which experienced the error.
255303

304+
### Pending
305+
306+
The `pending` entry in the response is a non-empty list of Pending Results. If
307+
the response of the GraphQL operation is an incremental stream, this field may
308+
appear on both the initial and subsequent responses. If present, the `pending`
309+
entry must contain at least one Pending Result.
310+
311+
Each Pending Result corresponds to either a `@defer` or `@stream` directive
312+
located at a specific path in the response data. The Pending Result is used to
313+
communicate that the GraphQL service has chosen to incrementally deliver the
314+
data associated with this `@defer` or `@stream` directive and clients should
315+
expect the associated data in either the current response, or one of the
316+
following responses.
317+
318+
**Pending Result Format**
319+
320+
Every Pending Result must contain an entry with the key `id` with a string
321+
value. This `id` should be used by clients to correlate Pending Results with
322+
Completed Results. The `id` value must be unique for the entire response stream.
323+
There must not be any other Pending Result in any response that contains the
324+
same `id`.
325+
326+
Every Pending Result must contain an entry with the key `path`. When the Pending
327+
Result is associated with a `@stream` directive, it indicates the response list
328+
field that is not known to be complete. Clients should expect the GraphQL
329+
Service to incrementally deliver the remainder of indicated list field. When the
330+
Pending Result is associated with a `@defer` directive, it indicates that the
331+
response fields contained in the deferred fragment are not known to be complete.
332+
Clients should expect the GraphQL Service to incrementally deliver the remainder
333+
of the fields contained in the deferred fragment.
334+
335+
If the associated `@defer` or `@stream` directive contains a `label` argument,
336+
the Pending Result must contain an entry `label` with the value of this
337+
argument.
338+
339+
If a Pending Result is not returned for a `@defer` or `@stream` directive,
340+
clients must assume that the GraphQL service chose not to incrementally deliver
341+
this data, and the data can be found either in the `data` entry in the initial
342+
response, or one of the Incremental Results in a prior subsequent response.
343+
344+
### Incremental
345+
346+
The `incremental` entry in the response is a non-empty list of Incremental
347+
Results. If the response of the GraphQL operation is an incremental stream, this
348+
field may appear on both the initial and subsequent responses. If present, the
349+
`incremental` entry must contain at least one Incremental Result.
350+
351+
The Incremental Result is used to deliver data that the GraphQL service has
352+
chosen to incrementally deliver. An Incremental Result may be ether an
353+
Incremental List Result or an Incremental Object Result.
354+
355+
An Incremental List Result is used to deliver additional list items for a list
356+
field with a `@stream` directive.
357+
358+
An Incremental Object Result is used to deliver additional response fields that
359+
were contained in one or more fragments with a `@defer` directive.
360+
361+
**Incremental Result Format**
362+
363+
Every Incremental Result must contain an entry with the key `id` with a string
364+
value. This `id` must match the `id` that was returned in a prior Pending
365+
Result.
366+
367+
Additionally, Incremental List Results and Incremental Object Results have
368+
further requirements.
369+
370+
**Incremental List 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 `@stream`
374+
directive.
375+
376+
The Incremental List Result's path can be determined using the prior Pending
377+
Result with the same `id` as this Incremental Result. The Incremental List
378+
Result's path is the same as the Pending Result's `path`.
379+
380+
Every Incremental List Result must contain an `items` entry. The `items` entry
381+
must contain a list of additional list items for the response field at the
382+
Incremental List Result's `path`. This output will be a list of the same type of
383+
the response field at this path.
384+
385+
If any field errors were raised during the execution of the results in `items`
386+
and these errors propagate to a path higher than the Incremental List Result's
387+
path, The Incremental List Result is considered failed and should not be
388+
included in the response stream. The errors that caused this failure will be
389+
included in a Completed Result.
390+
391+
If any field errors were raised during the execution of the results in `items`
392+
and these errors did not propagate to a path higher than the Incremental List
393+
Result's path, the Incremental List Result must contain an entry with key
394+
`errors` containing these field errors. The value of this entry is described in
395+
the "Errors" section.
396+
397+
**Incremental Object Result Format**
398+
399+
An Incremental Object Result's `id` entry must match the `id` that was returned
400+
in a prior Pending Result. This Pending Result must be associated with a
401+
`@defer` directive.
402+
403+
The Incremental Object Result's path can be determined using the prior Pending
404+
Result with the same `id` as this Incremental Result. The Incremental Object
405+
Result may contain a `subPath` entry. If the `subPath` entry is present, The
406+
Incremental Object Result's path can be determined by concatenating the Pending
407+
Result's `path` with this `subPath`. If no `subPath` entry is present, the path
408+
is the same as the Pending Result's `path`.
409+
410+
Every Incremental Object Result must contain a `data` entry. The `data` entry
411+
must contain a map of additional response fields. The `data` entry in an
412+
Incremental Object Result will be of the type of a particular field in the
413+
GraphQL result. The Incremental Object Result's path will contain the path
414+
segments of the field this data is associated with.
415+
416+
An Incremental Object Result's data may contain response fields that were
417+
contained in more than one deferred fragments. In that case, the `id` of the
418+
Incremental Object Result must point to the Pending Result that results in the
419+
shortest path.
420+
421+
If any field errors were raised during the execution of the results in `data`
422+
and these errors propagated to a path higher than the Incremental Object
423+
Result's path, The Incremental Object Result is considered failed and should not
424+
be included in the response stream. The errors that caused this failure will be
425+
included in a Completed Result.
426+
427+
If any field errors were raised during the execution of the results in `data`
428+
and these errors did not propagate to a path higher than the Incremental Object
429+
Result's path, the Incremental Object Result must contain an entry with key
430+
`errors` containing these field errors. The value of this entry is described in
431+
the "Errors" section.
432+
433+
### Completed
434+
435+
The `completed` entry in the response is a non-empty list of Completed Results.
436+
If the response of the GraphQL operation is an incremental stream, this field
437+
may appear on both the initial and subsequent responses. If present, the
438+
`completed` entry must contain at least one Completed Result.
439+
440+
Each Completed Result corresponds to a prior Pending Result. The Completed
441+
Result is used to communicate that the GraphQL service has completed the
442+
incremental delivery of the data associated with the corresponding Pending
443+
Result. The associated data must have been completed in the current response.
444+
445+
**Completed Result Format**
446+
447+
Every Completed Result must contain an entry with the key `id` with a string
448+
value. The `id` entry must match the `id` that was returned in a prior Pending
449+
Result.
450+
451+
A Completed Result may contain an `errors` entry. When the `errors` entry is
452+
present, it informs clients that the delivery of the data associated with the
453+
corresponding Pending Result has failed, due to an error bubbling to a path
454+
higher than the Incremental Data Result's path. The `errors` entry must contain
455+
these field errors. The value of this entry is described in the "Errors"
456+
section.
457+
256458
## Serialization Format
257459

258460
GraphQL does not require a specific serialization format. However, clients

0 commit comments

Comments
 (0)