Skip to content

Commit 9beddfc

Browse files
committed
Improved examples.
- Examples match those of https://github.com/jaydenseric/apollo-upload-examples. - Added example cURL requests, fixing jaydenseric#6. - Added example request payloads.
1 parent bafdfc1 commit 9beddfc

File tree

1 file changed

+145
-37
lines changed

1 file changed

+145
-37
lines changed

readme.md

Lines changed: 145 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ An interoperable [multipart form](https://tools.ietf.org/html/rfc7578) field str
66

77
It’s possible to implement:
88

9-
* Files nested anywhere within operations (typically in `variables`).
10-
* Batched operations.
9+
* Nesting files anywhere within operations (usually in `variables`).
10+
* Operation batching.
1111
* File deduplication.
1212
* File upload streams in resolvers.
1313
* Aborting file uploads in resolvers.
@@ -26,82 +26,190 @@ So operations can be resolved while the files are still uploading, the fields ar
2626

2727
## Examples
2828

29-
### Avatar mutation
29+
### Single file
3030

3131
#### Operations
3232

3333
```js
3434
{
35-
query: '',
36-
operationName: 'updateAvatar',
35+
query: `
36+
mutation($file: Upload!) {
37+
uploadFile(file: $file) {
38+
id
39+
}
40+
}
41+
`,
3742
variables: {
38-
userId: '',
39-
image: File
43+
file: File // a.txt
4044
}
4145
}
4246
```
4347

44-
#### Multipart form fields
48+
#### cURL request
49+
50+
```shell
51+
curl localhost:3001/graphql \
52+
-F operations='{ "query": "mutation ($file: Upload!) { singleUpload(file: $file) { id } }", "variables": { "file": null } }' \
53+
-F map='{ "0": ["variables.file"] }' \
54+
-F 0=@a.txt
55+
```
56+
57+
#### Request payload
58+
59+
```
60+
--------------------------cec8e8123c05ba25
61+
Content-Disposition: form-data; name="operations"
62+
63+
{ "query": "mutation ($file: Upload!) { singleUpload(file: $file) { id } }", "variables": { "file": null } }
64+
--------------------------cec8e8123c05ba25
65+
Content-Disposition: form-data; name="map"
66+
67+
{ "0": ["variables.file"] }
68+
--------------------------cec8e8123c05ba25
69+
Content-Disposition: form-data; name="0"; filename="a.txt"
70+
Content-Type: text/plain
71+
72+
Alpha file content.
4573
46-
1. `operations`: `{"query": "…", "operationName": "updateAvatar", "variables": {"userId": "…", image: null}}`
47-
2. `map`: `{"1": ["variables.image"]}`
48-
3. `1`: File
74+
--------------------------cec8e8123c05ba25--
75+
```
4976

50-
### Gallery mutation
77+
### File list
5178

5279
#### Operations
5380

5481
```js
5582
{
56-
query: '',
57-
operationName: 'addToGallery',
83+
query: `
84+
mutation($files: [Upload!]!) {
85+
multipleUpload(files: $files) {
86+
id
87+
}
88+
}
89+
`,
5890
variables: {
59-
galleryId: '',
60-
images: [File, File, File]
91+
files: [
92+
File, // b.txt
93+
File // c.txt
94+
]
6195
}
6296
}
6397
```
6498

65-
#### Multipart form fields
99+
#### cURL request
100+
101+
```shell
102+
curl localhost:3001/graphql \
103+
-F operations='{ "query": "mutation($files: [Upload!]!) { multipleUpload(files: $files) { id } }", "variables": { "files": [null, null] } }' \
104+
-F map='{ "0": ["variables.files.0"], "1": ["variables.files.1"] }' \
105+
-F 0=@b.txt \
106+
-F 1=@c.txt
107+
```
108+
109+
#### Request payload
110+
111+
```
112+
--------------------------ec62457de6331cad
113+
Content-Disposition: form-data; name="operations"
114+
115+
{ "query": "mutation($files: [Upload!]!) { multipleUpload(files: $files) { id } }", "variables": { "files": [null, null] } }
116+
--------------------------ec62457de6331cad
117+
Content-Disposition: form-data; name="map"
118+
119+
{ "0": ["variables.files.0"], "1": ["variables.files.1"] }
120+
--------------------------ec62457de6331cad
121+
Content-Disposition: form-data; name="0"; filename="b.txt"
122+
Content-Type: text/plain
66123
67-
1. `operations`: `{"query": "…", "operationName": "addToGallery", "variables": {"galleryId": "…", images: [null, null, null]}}`
68-
2. `map`: `{"1": ["variables.images.0"], "2": ["variables.images.1"], "3": ["variables.images.2"]}`
69-
3. `1`: File
70-
4. `2`: File
71-
5. `3`: File
124+
Bravo file content.
72125
73-
### Batched mutations
126+
--------------------------ec62457de6331cad
127+
Content-Disposition: form-data; name="1"; filename="c.txt"
128+
Content-Type: text/plain
129+
130+
Charlie file content.
131+
132+
--------------------------ec62457de6331cad--
133+
```
134+
135+
### Batching
74136

75137
#### Operations
76138

77139
```js
78140
[
79141
{
80-
query: '',
81-
operationName: 'updateAvatar',
142+
query: `
143+
mutation($file: Upload!) {
144+
uploadFile(file: $file) {
145+
id
146+
}
147+
}
148+
`,
82149
variables: {
83-
userId: '',
84-
image: File
150+
file: File // a.txt
85151
}
86152
},
87153
{
88-
query: '',
89-
operationName: 'addToGallery',
154+
query: `
155+
mutation($files: [Upload!]!) {
156+
multipleUpload(files: $files) {
157+
id
158+
}
159+
}
160+
`,
90161
variables: {
91-
galleryId: '',
92-
images: [File, File, File]
162+
files: [
163+
File, // b.txt
164+
File // c.txt
165+
]
93166
}
94167
}
95168
]
96169
```
97170

98-
#### Multipart form fields
171+
#### cURL request
172+
173+
```shell
174+
curl localhost:3001/graphql \
175+
-F operations='[{ "query": "mutation ($file: Upload!) { singleUpload(file: $file) { id } }", "variables": { "file": null } }, { "query": "mutation($files: [Upload!]!) { multipleUpload(files: $files) { id } }", "variables": { "files": [null, null] } }]' \
176+
-F map='{ "0": ["0.variables.file"], "1": ["1.variables.files.0"], "2": ["1.variables.files.1"] }' \
177+
-F 0=@a.txt \
178+
-F 1=@b.txt \
179+
-F 2=@c.txt
180+
```
181+
182+
#### Request payload
183+
184+
```
185+
--------------------------627436eaefdbc285
186+
Content-Disposition: form-data; name="operations"
99187
100-
1. `operations`: `[{"query": "…", "operationName": "updateAvatar", "variables": {"userId": "…", image: null}}, {"query": "…", "operationName": "addToGallery", "variables": {"galleryId": "…", images: [null, null, null]}}]`
101-
2. `map`: `{"1": ["0.variables.image", "1.variables.images.0"], "2": ["1.variables.images.1"], "3": ["1.variables.images.2"]}`
102-
3. `1`: File
103-
4. `2`: File
104-
5. `3`: File
188+
[{ "query": "mutation ($file: Upload!) { singleUpload(file: $file) { id } }", "variables": { "file": null } }, { "query": "mutation($files: [Upload!]!) { multipleUpload(files: $files) { id } }", "variables": { "files": [null, null] } }]
189+
--------------------------627436eaefdbc285
190+
Content-Disposition: form-data; name="map"
191+
192+
{ "0": ["0.variables.file"], "1": ["1.variables.files.0"], "2": ["1.variables.files.1"] }
193+
--------------------------627436eaefdbc285
194+
Content-Disposition: form-data; name="0"; filename="a.txt"
195+
Content-Type: text/plain
196+
197+
Alpha file content.
198+
199+
--------------------------627436eaefdbc285
200+
Content-Disposition: form-data; name="1"; filename="b.txt"
201+
Content-Type: text/plain
202+
203+
Bravo file content.
204+
205+
--------------------------627436eaefdbc285
206+
Content-Disposition: form-data; name="2"; filename="c.txt"
207+
Content-Type: text/plain
208+
209+
Charlie file content.
210+
211+
--------------------------627436eaefdbc285--
212+
```
105213

106214
## Implementations
107215

0 commit comments

Comments
 (0)