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

Commit 633ca8b

Browse files
maraisrrobrichard
authored andcommitted
[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 c736cea commit 633ca8b

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'),
@@ -2453,16 +2437,12 @@ function runTests(server: Server) {
24532437
'',
24542438
'---',
24552439
'Content-Type: application/json; charset=utf-8',
2456-
'Content-Length: 48',
24572440
'',
24582441
'{"data":{"test2":"Modification"},"hasNext":true}',
2459-
'',
24602442
'---',
24612443
'Content-Type: application/json; charset=utf-8',
2462-
'Content-Length: 64',
24632444
'',
24642445
'{"errors":[{"message":"I did something wrong"}],"hasNext":false}',
2465-
'',
24662446
'-----',
24672447
'',
24682448
].join('\r\n'),
@@ -2527,10 +2507,9 @@ function runTests(server: Server) {
25272507
'',
25282508
'---',
25292509
'Content-Type: application/json; charset=utf-8',
2530-
'Content-Length: 47',
25312510
'',
25322511
'{"data":{"test":"Hello, World"},"hasNext":true}',
2533-
'',
2512+
'---\r\n',
25342513
].join('\r\n'),
25352514
);
25362515
expect(fakeReturn.callCount).to.equal(1);
@@ -2592,10 +2571,9 @@ function runTests(server: Server) {
25922571
'',
25932572
'---',
25942573
'Content-Type: application/json; charset=utf-8',
2595-
'Content-Length: 47',
25962574
'',
25972575
'{"data":{"test":"Hello, World"},"hasNext":true}',
2598-
'',
2576+
'---\r\n',
25992577
].join('\r\n'),
26002578
);
26012579
});
@@ -2748,16 +2726,12 @@ function runTests(server: Server) {
27482726
'',
27492727
'---',
27502728
'Content-Type: application/json; charset=utf-8',
2751-
'Content-Length: 124',
27522729
'',
27532730
'{"data":{"hello":"Hello Rob"},"hasNext":true,"extensions":{"preservedResult":{"data":{"hello":"Hello Rob"},"hasNext":true}}}',
2754-
'',
27552731
'---',
27562732
'Content-Type: application/json; charset=utf-8',
2757-
'Content-Length: 148',
27582733
'',
27592734
'{"data":{"test":"Hello World"},"path":[],"hasNext":false,"extensions":{"preservedResult":{"data":{"test":"Hello World"},"path":[],"hasNext":false}}}',
2760-
'',
27612735
'-----',
27622736
'',
27632737
].join('\r\n'),
@@ -2828,16 +2802,12 @@ function runTests(server: Server) {
28282802
'',
28292803
'---',
28302804
'Content-Type: application/json; charset=utf-8',
2831-
'Content-Length: 45',
28322805
'',
28332806
'{"data":{"hello":"Hello Rob"},"hasNext":true}',
2834-
'',
28352807
'---',
28362808
'Content-Type: application/json; charset=utf-8',
2837-
'Content-Length: 57',
28382809
'',
28392810
'{"data":{"test":"Hello World"},"path":[],"hasNext":false}',
2840-
'',
28412811
'-----',
28422812
'',
28432813
].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)