fastify-type-provider-json-schema-to-ts
fastify-type-provider-json-schema-to-ts copied to clipboard
Unknown request body when using onRequest hook
Prerequisites
- [X] I have written a descriptive issue title
- [X] I have searched existing issues to ensure the issue has not already been raised
Issue
When using a hook like onRequest
, the schema validation doesn't work anymore. If e.g. a body schema is specified in MySchema
, the request body will be of type unknown
:
const appWithTypeProvider = app.withTypeProvider<JsonSchemaToTsProvider>();
appWithTypeProvider.post('/', {schema: MySchema, onRequest: randomMethod}, async (request) => {
request.body // unknown
});
Is this wanted behaviour?
Notice: in the onRequest hook, request.body will always be undefined, because the body parsing happens before the preValidation hook.
https://www.fastify.io/docs/latest/Reference/Hooks/#onrequest
Checkout the hooks execution order here: https://www.fastify.io/docs/latest/Reference/Lifecycle/#lifecycle
In this case, the body is also of type unknown when using a preHandler hook. According to https://www.fastify.io/docs/latest/Reference/Lifecycle/#lifecycle, the preHandler hook is called after the validation, so it should be defined right?
the preHandler hook is called after the validation, so it should be defined right?
Yes, the body is set on that time
In this case, the body is also of type unknown when using a preHandler hook. According to https://www.fastify.io/docs/latest/Reference/Lifecycle/#lifecycle, the preHandler hook is called after the validation, so it should be defined right?
I stumbled on to the same issue with the preHandler hook. So if I define the schema and use an inline hook, the request body is inferred correctly in the actual handler:
server.post(
"/items",
{
schema: {
body: {
type: "object",
properties: {
name: {
type: "string",
},
},
required: ["name"],
} as const,
},
// Inline dummy hook
preHandler: async (request, reply) => {},
},
async (request, reply) => {
// No problems here, request.body.name is a string like it should be
console.log(request.body.name);
}
);
However, if I extract the hook into its own function (for reuse purposes and whatnot), then request.body
is unknown
:
const dummyHook = async (request: FastifyRequest, reply: FastifyReply) => {};
server.post(
"/items",
{
schema: {
body: {
type: "object",
properties: {
name: {
type: "string",
},
},
required: ["name"],
} as const,
},
// Hook is now a dedicated function
preHandler: dummyHook
},
async (request, reply) => {
// TS2571: Object is of type 'unknown'.
console.log(request.body.name);
}
);
Is this expected behaviour? Reusing hooks sounds like a common scenario so I might be missing something. One way to work around this is to call the shared hook from the inline hook but it comes off as being a bit redundant:
{
schema: {
...
},
preHandler: async (request, reply) => {
await dummyHook(request, reply);
},
},
async (request, reply) => {
// No problems here, request.body.name is a string like it should be
console.log(request.body.name);
}
I'm also facing issue described in last comment.
@Eomm maybe it worth to reopen this for visibility that specifying preHandler
with dedicated function breaks typing? Or maybe just add a README note about "known issue" and workaround for it.
Please re-open. I've been hitting this issue as well and haven't found a feel-good work-around. @mcollina.
Ran into this issue as well with type information being lost when using a prehandler that is an external method