middleware icon indicating copy to clipboard operation
middleware copied to clipboard

(zod-openapi) Return type of `handler` doesn't respect the schema strictness

Open masnormen opened this issue 2 years ago • 4 comments

Hi, I'm having a problem making sure the return type of a handler to be as strict as the defined zod schema in createRoute. Consider the following code:

const app = new OpenAPIHono().openapi(
  createRoute({
    summary: 'Test route',
    method: 'post',
    path: '/test',
    responses: {
      200: {
        description: 'test',
        content: {
          'application/json': {
            schema: z
              .object({
                name: z.string(),
              })
              .strict(), // <= a supposedly strict schema for { name: string; }
          },
        },
      },
    },
  }),
  (c) => {
    return c.jsonT({
      name: 'John Doe',
    });
  }
);

However, it seems that zod-openapi doesn't do a type parse/validation on return type. The following handler which returns an extra property/key also works, and doesn't throw an error:

(c) => {
  return c.jsonT({
    name: 'John Doe',
+    age: 12,
  });
}

This could make the API less safe/secure. For example after fetching user data from a DB table, the developer could accidentally return the user data without omitting the password fields first, because TypeScript doesn't complain about the extra "password" field.

I think this is related to the usage of z.infer in the OutputType<R> type, which I guess can be fixed by either:

  • raising a runtime error (i.e. invoking a z.parse() on the response) (using an extra middleware?)
  • or using advanced TypeScript typechecking tricks

Is there a workaround for making sure the type is exactly the same? Or is there something I'm missing? Anyway thank you for the amazing works!

masnormen avatar Sep 28 '23 09:09 masnormen

Hi! @masnormen

You are correct, Hono's Validator does not validate the response. What Zod OpenAPI does now is very loose validation. I would like to think about this issue. Thanks.

yusukebe avatar Sep 29 '23 02:09 yusukebe

Hi. I've found a solution for this issue and would like to propose a PR soon. Thanks for the response!

masnormen avatar Sep 29 '23 03:09 masnormen

Great! Waiting!

yusukebe avatar Sep 29 '23 03:09 yusukebe

@masnormen what was your solution?

npearson72 avatar Jan 28 '25 14:01 npearson72