Can we generate an openapi schema from any existing hono app?
What is the feature you are proposing?
I'm using zod validator, just like the technique described here. Is there a way I can generate an openapi schema from this app?
Regarding Swagger UI and Zod OpenApi, is my assumption correct that they cannot generate an openapi schema for a hono app, unless that hono app uses Zod OpenApi to explicitly declare the shape of each endpoint using createRoute()?
Hono client does a really great job of inferring the request types, response types, status codes, etc when using zod-validator. However, I couldn't figure out how to make it generate an openapi schema or a swagger ui, despite all of the strong typing afforded to us by zod-validator. I'd just like to make sure that this not currently possible, and not due to a misunderstanding on my part.
The closest I got was this (using chanfana):
import { fromHono } from "chanfana";
import { zValidator } from "@hono/zod-validator";
import { z } from "zod";
import { Hono } from "hono";
import { serve } from "@hono/node-server";
const _app = new Hono();
const app = fromHono(_app);
const route = app.get(
"/hello",
zValidator("query", z.object({ name: z.string() })),
(c) => {
const { name } = c.req.valid("query");
if (name === "") {
return c.json({ error_title: "Invalid name" }, 400);
}
return c.json({ message: `Hello! ${name}` }, 202);
},
);
serve({ fetch: app.fetch, port: 3000 });
But it wasn't very intelligent as it did not make use of all the available type information. Here is what we get when we run it then call curl http://localhost:3000/openapi.json:
{
"openapi": "3.1.0",
"info": {
"version": "1.0.0",
"title": "OpenAPI",
},
"components": {
"schemas": {},
"parameters": {},
},
"paths": {
"/hello": {
"get": {
"operationId": "get__hello",
"responses": {
"200": {
"description": "Successful response.",
},
},
},
},
},
"webhooks": {},
}
It incorrectly assumed our endpoint returned status of 200 (instead of 202 or 400). It also did not capture the response shape.
Now compare that with how Hono client make use of the rich static typing (focus on the final 3 lines):
typescript playground: link
import { hc } from "hono/client";
import { zValidator } from "@hono/zod-validator";
import { z } from "zod";
import { Hono } from "hono";
const app = new Hono();
// Server
const route = app.get(
"/hello",
zValidator("query", z.object({ name: z.string() })),
(c) => {
const { name } = c.req.valid("query");
if (name === "") {
return c.json({ error_title: "Invalid name" }, 400);
}
return c.json({ message: `Hello! ${name}` }, 202);
},
);
// Client
const api = hc<typeof route>("");
const res = await api.hello.$get({ query: { name: "" } });
if (!res.ok) {
const data = await res.json();
console.log(data.message); // this line has a useful typescript error because hono client knows that `message` property can never exist here!
console.log(data.error_title); // this is OK
}
I'm aware this is operating on the type-level (not runtime), but I was wondering if there are some type reflection tools that would make this feature request possible? Especially given that all the required type information is available.