Skip to content
This repository was archived by the owner on Mar 20, 2023. It is now read-only.

Commit c396288

Browse files
authored
[incremental-delivery]: Remove the content-length requirement (#728)
This removes the need for `Content-Length`, and handles the boundaries such that the next boundary is flushed as soon as possible. References: - graphql/graphql-over-http#152 - fmg relay-tools/fetch-multipart-graphql#22 - [meros](https://github.com/maraisr/meros)
1 parent 14b01c8 commit c396288

File tree

2 files changed

+11
-43
lines changed

2 files changed

+11
-43
lines changed

src/__tests__/http-test.ts

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,16 +1074,12 @@ function runTests(server: Server) {
10741074
'',
10751075
'---',
10761076
'Content-Type: application/json; charset=utf-8',
1077-
'Content-Length: 26',
10781077
'',
10791078
'{"data":{},"hasNext":true}',
1080-
'',
10811079
'---',
10821080
'Content-Type: application/json; charset=utf-8',
1083-
'Content-Length: 78',
10841081
'',
10851082
'{"data":{"test":"Hello World"},"path":[],"label":"deferLabel","hasNext":false}',
1086-
'',
10871083
'-----',
10881084
'',
10891085
].join('\r\n'),
@@ -1204,13 +1200,10 @@ function runTests(server: Server) {
12041200
'',
12051201
'---',
12061202
'Content-Type: application/json; charset=utf-8',
1207-
'Content-Length: 35',
12081203
'',
12091204
['{', ' "data": {},', ' "hasNext": true', '}'].join('\n'),
1210-
'',
12111205
'---',
12121206
'Content-Type: application/json; charset=utf-8',
1213-
'Content-Length: 79',
12141207
'',
12151208
[
12161209
'{',
@@ -1221,7 +1214,6 @@ function runTests(server: Server) {
12211214
' "hasNext": false',
12221215
'}',
12231216
].join('\n'),
1224-
'',
12251217
'-----',
12261218
'',
12271219
].join('\r\n'),
@@ -1413,16 +1405,12 @@ function runTests(server: Server) {
14131405
'',
14141406
'---',
14151407
'Content-Type: application/json; charset=utf-8',
1416-
'Content-Length: 94',
14171408
'',
14181409
'{"errors":[{"message":"Custom error format: Throws!"}],"data":{"thrower":null},"hasNext":true}',
1419-
'',
14201410
'---',
14211411
'Content-Type: application/json; charset=utf-8',
1422-
'Content-Length: 57',
14231412
'',
14241413
'{"data":{"test":"Hello World"},"path":[],"hasNext":false}',
1425-
'',
14261414
'-----',
14271415
'',
14281416
].join('\r\n'),
@@ -1464,16 +1452,12 @@ function runTests(server: Server) {
14641452
'',
14651453
'---',
14661454
'Content-Type: application/json; charset=utf-8',
1467-
'Content-Length: 46',
14681455
'',
14691456
'{"data":{"test":"Hello World"},"hasNext":true}',
1470-
'',
14711457
'---',
14721458
'Content-Type: application/json; charset=utf-8',
1473-
'Content-Length: 105',
14741459
'',
14751460
'{"data":{"thrower":null},"path":[],"errors":[{"message":"Custom error format: Throws!"}],"hasNext":false}',
1476-
'',
14771461
'-----',
14781462
'',
14791463
].join('\r\n'),
@@ -2426,16 +2410,12 @@ function runTests(server: Server) {
24262410
'',
24272411
'---',
24282412
'Content-Type: application/json; charset=utf-8',
2429-
'Content-Length: 48',
24302413
'',
24312414
'{"data":{"test2":"Modification"},"hasNext":true}',
2432-
'',
24332415
'---',
24342416
'Content-Type: application/json; charset=utf-8',
2435-
'Content-Length: 64',
24362417
'',
24372418
'{"errors":[{"message":"I did something wrong"}],"hasNext":false}',
2438-
'',
24392419
'-----',
24402420
'',
24412421
].join('\r\n'),
@@ -2500,10 +2480,9 @@ function runTests(server: Server) {
25002480
'',
25012481
'---',
25022482
'Content-Type: application/json; charset=utf-8',
2503-
'Content-Length: 47',
25042483
'',
25052484
'{"data":{"test":"Hello, World"},"hasNext":true}',
2506-
'',
2485+
'---\r\n',
25072486
].join('\r\n'),
25082487
);
25092488
expect(fakeReturn.callCount).to.equal(1);
@@ -2565,10 +2544,9 @@ function runTests(server: Server) {
25652544
'',
25662545
'---',
25672546
'Content-Type: application/json; charset=utf-8',
2568-
'Content-Length: 47',
25692547
'',
25702548
'{"data":{"test":"Hello, World"},"hasNext":true}',
2571-
'',
2549+
'---\r\n',
25722550
].join('\r\n'),
25732551
);
25742552
});
@@ -2721,16 +2699,12 @@ function runTests(server: Server) {
27212699
'',
27222700
'---',
27232701
'Content-Type: application/json; charset=utf-8',
2724-
'Content-Length: 124',
27252702
'',
27262703
'{"data":{"hello":"Hello Rob"},"hasNext":true,"extensions":{"preservedResult":{"data":{"hello":"Hello Rob"},"hasNext":true}}}',
2727-
'',
27282704
'---',
27292705
'Content-Type: application/json; charset=utf-8',
2730-
'Content-Length: 148',
27312706
'',
27322707
'{"data":{"test":"Hello World"},"path":[],"hasNext":false,"extensions":{"preservedResult":{"data":{"test":"Hello World"},"path":[],"hasNext":false}}}',
2733-
'',
27342708
'-----',
27352709
'',
27362710
].join('\r\n'),
@@ -2801,16 +2775,12 @@ function runTests(server: Server) {
28012775
'',
28022776
'---',
28032777
'Content-Type: application/json; charset=utf-8',
2804-
'Content-Length: 45',
28052778
'',
28062779
'{"data":{"hello":"Hello Rob"},"hasNext":true}',
2807-
'',
28082780
'---',
28092781
'Content-Type: application/json; charset=utf-8',
2810-
'Content-Length: 57',
28112782
'',
28122783
'{"data":{"test":"Hello World"},"path":[],"hasNext":false}',
2813-
'',
28142784
'-----',
28152785
'',
28162786
].join('\r\n'),

src/index.ts

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,7 @@ export function graphqlHTTP(options: Options): Middleware {
462462

463463
if (isAsyncIterable(executeResult)) {
464464
response.setHeader('Content-Type', 'multipart/mixed; boundary="-"');
465+
response.write('\r\n---\r\n');
465466
sendPartialResponse(pretty, response, formattedResult);
466467
try {
467468
for await (let payload of executeResult) {
@@ -489,7 +490,6 @@ export function graphqlHTTP(options: Options): Middleware {
489490
hasNext: false,
490491
});
491492
}
492-
response.write('\r\n-----\r\n');
493493
response.end();
494494
finishedIterable = true;
495495
return;
@@ -625,16 +625,14 @@ function sendPartialResponse(
625625
): void {
626626
const json = JSON.stringify(result, null, pretty ? 2 : 0);
627627
const chunk = Buffer.from(json, 'utf8');
628-
const data = [
629-
'',
630-
'---',
631-
'Content-Type: application/json; charset=utf-8',
632-
'Content-Length: ' + String(chunk.length),
633-
'',
634-
chunk,
635-
'',
636-
].join('\r\n');
637-
response.write(data);
628+
const data = ['Content-Type: application/json; charset=utf-8', '', chunk];
629+
// @ts-expect-error
630+
if (result.hasNext === true) {
631+
data.push('---\r\n');
632+
} else {
633+
data.push('-----\r\n');
634+
}
635+
response.write(data.join('\r\n'));
638636
// flush response if compression middleware is used
639637
if (
640638
typeof response.flush === 'function' &&

0 commit comments

Comments
 (0)