Skip to content

Commit 9eec51b

Browse files
committed
Spec edits for incremental delivery, Examples
1 parent bcb92a2 commit 9eec51b

File tree

2 files changed

+193
-0
lines changed

2 files changed

+193
-0
lines changed

spec/Appendix C -- Examples.md

+191
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
# C. Appendix: Examples
2+
3+
## Incremental Delivery Examples
4+
5+
### Example 1 - A query containing both defer and stream
6+
7+
```graphql example
8+
query {
9+
person(id: "cGVvcGxlOjE=") {
10+
...HomeWorldFragment @defer(label: "homeWorldDefer")
11+
name
12+
films @stream(initialCount: 1, label: "filmsStream") {
13+
title
14+
}
15+
}
16+
}
17+
fragment HomeWorldFragment on Person {
18+
homeWorld {
19+
name
20+
}
21+
}
22+
```
23+
24+
The incremental stream might look like:
25+
26+
The initial response does not contain any deferred or streamed results in the
27+
`data` entry. The initial response contains a `hasNext` entry, indicating that
28+
subsequent responses will be delivered. There are two Pending Responses
29+
indicating that results for both the `@defer` and `@stream` in the query will be
30+
delivered in the subsequent responses.
31+
32+
```json example
33+
{
34+
"data": {
35+
"person": {
36+
"name": "Luke Skywalker",
37+
"films": [{ "title": "A New Hope" }]
38+
}
39+
},
40+
"pending": [
41+
{ "id": "0", "path": ["person"], "label": "homeWorldDefer" },
42+
{ "id": "1", "path": ["person", "films"], "label": "filmsStream" }
43+
],
44+
"hasNext": true
45+
}
46+
```
47+
48+
Subsequent response 1, contains the deferred data and the first streamed list
49+
item. There is one Completed Result, indicating that the deferred data has been
50+
completely delivered.
51+
52+
```json example
53+
{
54+
"incremental": [
55+
{
56+
"id": "0",
57+
"data": { "homeWorld": { "name": "Tatooine" } }
58+
},
59+
{
60+
"id": "1",
61+
"items": [{ "title": "The Empire Strikes Back" }]
62+
}
63+
],
64+
"completed": [
65+
{"id": "0"}
66+
]
67+
"hasNext": true
68+
}
69+
```
70+
71+
Subsequent response 2, contains the final stream results. In this example, the
72+
underlying iterator does not close synchronously so {hasNext} is set to {true}.
73+
If this iterator did close synchronously, {hasNext} would be set to {false} and
74+
this would be the final response.
75+
76+
```json example
77+
{
78+
"incremental": [
79+
{
80+
"id": "1",
81+
"items": [{ "title": "Return of the Jedi" }]
82+
}
83+
],
84+
"hasNext": true
85+
}
86+
```
87+
88+
Subsequent response 3, contains no incremental data. {hasNext} set to {false}
89+
indicates the end of the incremental stream. This response is sent when the
90+
underlying iterator of the `films` field closes.
91+
92+
```json example
93+
{
94+
"hasNext": false
95+
}
96+
```
97+
98+
### Example 2 - A query containing overlapping defers
99+
100+
```graphql example
101+
query {
102+
person(id: "cGVvcGxlOjE=") {
103+
...HomeWorldFragment @defer(label: "homeWorldDefer")
104+
...NameAndHomeWorldFragment @defer(label: "nameAndWorld")
105+
firstName
106+
}
107+
}
108+
fragment HomeWorldFragment on Person {
109+
homeWorld {
110+
name
111+
terrain
112+
}
113+
}
114+
115+
fragment NameAndHomeWorldFragment on Person {
116+
firstName
117+
lastName
118+
homeWorld {
119+
name
120+
}
121+
}
122+
```
123+
124+
The incremental stream might look like:
125+
126+
The initial response contains the results of the `firstName` field. Even though
127+
it is also present in the `HomeWorldFragment`, it must be returned in the
128+
initial response because it is also defined outside of any fragments with the
129+
`@defer` directive. Additionally, There are two Pending Responses indicating
130+
that results for both `@defer`s in the query will be delivered in the subsequent
131+
responses.
132+
133+
```json example
134+
{
135+
"data": {
136+
"person": {
137+
"firstName": "Luke"
138+
}
139+
},
140+
"pending": [
141+
{ "id": "0", "path": ["person"], "label": "homeWorldDefer" },
142+
{ "id": "1", "path": ["person"], "label": "nameAndWorld" }
143+
],
144+
"hasNext": true
145+
}
146+
```
147+
148+
Subsequent response 1, contains the deferred data from `HomeWorldFragment`.
149+
There is one Completed Result, indicating that `HomeWorldFragment` has been
150+
completely delivered. Because the `homeWorld` field is present in two separate
151+
`@defer`s, it is separated into its own Incremental Result.
152+
153+
The second Incremental Result contains the data for the `terrain` field. This
154+
incremental result contains a `subPath` property to indicate to clients that the
155+
path of this result can be determined by concatenating the path from the Pending
156+
Result with id `"0"` and this `subPath` entry.
157+
158+
```json example
159+
{
160+
"incremental": [
161+
{
162+
"id": "0",
163+
"data": { "homeWorld": { "name": "Tatooine" } }
164+
},
165+
{
166+
"id": "0",
167+
"subPath": ["homeWorld"],
168+
"data": { "terrain": "desert" }
169+
}
170+
],
171+
"completed": [{ "id": "0" }],
172+
"hasNext": true
173+
}
174+
```
175+
176+
Subsequent response 2, contains the remaining data from the
177+
`NameAndHomeWorldFragment`. `lastName` is the only remaining field that has not
178+
been delivered in a previous response.
179+
180+
```json example
181+
{
182+
"incremental": [
183+
{
184+
"id": "1",
185+
"data": { "lastName": "Skywalker" }
186+
}
187+
],
188+
"completed": [{ "id": "1" }],
189+
"hasNext": false
190+
}
191+
```

spec/GraphQL.md

+2
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,5 @@ Note: This is an example of a non-normative note.
139139
# [Appendix: Notation Conventions](Appendix%20A%20--%20Notation%20Conventions.md)
140140

141141
# [Appendix: Grammar Summary](Appendix%20B%20--%20Grammar%20Summary.md)
142+
143+
# [Appendix: Examples](Appendix%20C%20--%20Examples.md)

0 commit comments

Comments
 (0)