Skip to content

Commit 268a4bf

Browse files
committed
feat(handler): Request's body field may be a parser function
1 parent da90442 commit 268a4bf

File tree

2 files changed

+30
-9
lines changed

2 files changed

+30
-9
lines changed

docs/interfaces/Request.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,12 @@ which is server dependant.
2727

2828
### body
2929

30-
`Readonly` **body**: ``null`` \| `string` \| `Record`<`string`, `unknown`\>
30+
`Readonly` **body**: ``null`` \| `string` \| `Record`<`string`, `unknown`\> \| () => ``null`` \| `string` \| `Record`<`string`, `unknown`\> \| `Promise`<``null`` \| `string` \| `Record`<`string`, `unknown`\>\>
31+
32+
Parsed request body or a parser function.
33+
34+
If the provided function throws, the error message "Unparsable JSON body" will
35+
be in the erroneous response.
3136

3237
___
3338

src/handler.ts

+24-8
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,21 @@ export interface Request<RawRequest, Context> {
5252
readonly method: string;
5353
readonly url: string;
5454
readonly headers: RequestHeaders;
55-
readonly body: string | Record<string, unknown> | null;
55+
/**
56+
* Parsed request body or a parser function.
57+
*
58+
* If the provided function throws, the error message "Unparsable JSON body" will
59+
* be in the erroneous response.
60+
*/
61+
readonly body:
62+
| string
63+
| Record<string, unknown>
64+
| null
65+
| (() =>
66+
| string
67+
| Record<string, unknown>
68+
| null
69+
| Promise<string | Record<string, unknown> | null>);
5670
/**
5771
* The raw request itself from the implementing server.
5872
*
@@ -412,16 +426,18 @@ export function createHandler<RawRequest = unknown, Context = unknown>(
412426
if (!req.body) {
413427
throw new Error('Missing body');
414428
}
429+
let data;
415430
try {
416-
const data =
417-
typeof req.body === 'string' ? JSON.parse(req.body) : req.body;
418-
partParams.operationName = data.operationName;
419-
partParams.query = data.query;
420-
partParams.variables = data.variables;
421-
partParams.extensions = data.extensions;
422-
} catch {
431+
const body =
432+
typeof req.body === 'function' ? await req.body() : req.body;
433+
data = typeof body === 'string' ? JSON.parse(body) : body;
434+
} catch (err) {
423435
throw new Error('Unparsable JSON body');
424436
}
437+
partParams.operationName = data.operationName;
438+
partParams.query = data.query;
439+
partParams.variables = data.variables;
440+
partParams.extensions = data.extensions;
425441
break;
426442
}
427443
default: // graphql-http doesnt support any other content type

0 commit comments

Comments
 (0)