-
Notifications
You must be signed in to change notification settings - Fork 205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[zod-openapi] Support ZodLazy #643
Comments
Any update so far? I'm facing the same issue |
Facing the same issue, did you find a workaround to support recursive types? |
Sadly there is no other way than lazy |
I ended up overwriting type with the
I'm sure there is a better way to define the openapi schema but this at least does not break the spec generation |
I found the solution. import { serve } from "@hono/node-server";
import { swaggerUI } from "@hono/swagger-ui";
import { createRoute, OpenAPIHono } from "@hono/zod-openapi";
import { z } from "@hono/zod-openapi";
import { zodToJsonSchema } from "zod-to-json-schema";
const baseCategorySchema = z.object({ name: z.string() });
type Category = z.infer<typeof baseCategorySchema> & {
subcategories: Category[];
};
const categorySchemaRaw: z.ZodType<Category> = baseCategorySchema.extend({
subcategories: z.lazy(() => categorySchemaRaw.array()),
});
const name = "Category";
const jsonSchema = zodToJsonSchema(categorySchemaRaw, {
basePath: [`#/components/schemas/${name}`],
});
// console.dir(jsonSchema, { depth: null });
const schema = categorySchemaRaw.openapi(name, jsonSchema as {}).openapi({
example: {
name: "test1",
subcategories: [
{
name: "test2",
subcategories: [],
},
],
},
});
const app = new OpenAPIHono({ strict: false });
app.openapi(
createRoute({
method: "post",
path: "/test",
request: { body: { content: { "application/json": { schema } } } },
responses: { 200: { description: "test" } },
}),
(c) => c.text("test"),
);
type OpenAPIObjectConfig = Parameters<typeof app.getOpenAPIDocument>[0];
const config: OpenAPIObjectConfig = {
openapi: "3.0.3",
info: { version: "0.0.1", title: "Some API" },
};
const pathOpenAPI = "/openapi";
app.doc(pathOpenAPI, config);
app.get("/swagger-ui", swaggerUI({ url: pathOpenAPI }));
serve({
async fetch(req, env) {
return app.fetch(req, env);
},
port: 4001,
});
// eslint-disable-next-line no-console
console.log(`Server is running on port 4001`);
// const schemaOpenAPI = app.getOpenAPIDocument(config);
// console.dir(schemaOpenAPI, { depth: null }); In swagger UI Category is correctly shown recursively with correct types instead of just Also this approach is very convenient to use when you have all your zodiac schemas in one file with a script that converts each zod schema to use openapi with In my case I generate zod types from prisma schema using |
Thank you for this, will look into it :) I still think it could be a great improvement for Hono ! |
@yusukebe is this a problem inherited from @asteasolutions/zod-to-openapi? |
Hi all. I do not fully understand this problem. I think we can define the recursive types with the following code. Is not enough? import { createRoute, OpenAPIHono } from '@hono/zod-openapi'
import { z } from '@hono/zod-openapi'
interface Category {
name: string
subcategories: Category[]
}
const CategorySchema: z.ZodSchema<Category> = z.lazy(() =>
z.object({
name: z.string(),
subcategories: z.array(CategorySchema)
})
)
const route = createRoute({
method: 'post',
path: '/',
request: {
body: {
content: {
'application/json': {
schema: z.object({
category: CategorySchema
})
}
}
}
},
responses: {
200: {
description: 'Return data'
}
}
})
const app = new OpenAPIHono()
app.openapi(route, (c) => {
const data = c.req.valid('json')
return c.json(data)
})
export default app |
this is an issue with |
Similarly to how
zod-openapi
does it:https://github.com/samchungy/zod-openapi/tree/master?tab=readme-ov-file#supported-zod-schema
Currently, we get the following error:
A good example of usage would be the JSON schema from Zod's documentation:
The text was updated successfully, but these errors were encountered: