Zod-OpenAPI not performing strict validation on response schemas
Which middleware has the bug?
@hono/zod-openapi
What version of the middleware?
0.18.3
What version of Hono are you using?
4.6.14
What runtime/platform is your app running on? (with version if possible)
Node 20.17.0
What steps can reproduce the bug?
- Create a select schema with drizzle-zod. Add a .omit() option to omit some fields and add .strict() to make sure that extra fields are not accepted.
- Assign the schema to a response with the createRoute API
What is the expected behavior?
- When passing an object that has fields that are not included in the schema to c.json(), the response should be seen as invalid and throw a type error.
What do you see instead?
- No error is shown, and the response is seen as valid.
Additional information
I have tested the schema and I can clearly see from the openAPI specs that "additionalProperties" is set to false. Also, I can see from the autocomplete on c.json() that the schema does indeed exclude the extra properties that I am passing.
However, I can still pass extra fields and I get no error. I only get an error if I am manually parsing the response with zod.
Hi @Rick-Phoenix
Thank you for the issue. It is a known issue that the Zod OpenAPI can't validate the value of the response: https://github.com/honojs/middleware/issues/181
function strictJSONResponse<
C extends Context,
S extends ZodSchema,
U extends StatusCode
>(c: C, schema: S, data: Parameters<Context['json']>[0], statusCode: U) {
const validatedResponse = schema.safeParse(data);
if (!validatedResponse.success) {
return c.json(
{
message: 'Strict response validation failed',
},
500
);
}
return c.json(validatedResponse.data as z.infer<S>, statusCode);
}
worked for me. maybe we could make this a helper?
Would that work with parseAsync too?
@Rick-Phoenix yes just make your function async
@askorupskyy
Ah, I'm also considering the same approach: using a helper to validate the data before c.json()! This approach may not be only Zod OpenAPI function, but we can make it a more general feature in the hono core package.
I have extended the example code by @askorupskyy to give you IDE feedback when the passed in data is incorrect
import type { Context } from "hono";
import type { ContentfulStatusCode } from "hono/utils/http-status";
import type { z, ZodSchema } from "zod";
export function strictJSONResponse<
C extends Context,
S extends ZodSchema,
D extends Parameters<Context["json"]>[0] & z.infer<S>,
U extends ContentfulStatusCode
>(c: C, schema: S, data: D, statusCode?: U) {
const validatedResponse = schema.safeParse(data);
if (!validatedResponse.success) {
return c.json(
{
message: "Strict response validation failed",
},
500
);
}
return c.json(validatedResponse.data, statusCode);
}