This is an Open API Schema Generator for Hono with typia.
npm install hono-typia-openapi
You can use the hto
command or Plugins to generate the OpenAPI schema.
hto -a <app-file> -t <title>
And, in <app-file>, you write the following:
import { Hono } from "hono";
import typia, { tags } from "typia";
import { typiaValidator } from "@hono/typia-validator";
interface HelloRequest {
/** Your name */
name: string & tags.MaxLength<16>;
}
const app = new Hono()
.get("/hello", (c) => {
return c.json(200, { message: "Hello, World!" });
})
.post(
"/hello",
typiaValidator("json", typia.createValidator<HelloRequest>()),
(c) => {
const { name } = c.req.valid("json");
return c.json(200, { message: `Hello, ${name}!` });
},
);
// Generator uses this type to get the application schema.
export type AppType = typeof app;
Then, you can get the OpenAPI schema in the openapi.json
file.
You can specify the following options:
Option | Description |
---|---|
-t, --title <title> | The title of the application |
-O, --openapi <openapi> | The version of the OpenAPI specification. ['3.1', '3.0'] (default: 3.1) |
-d, --description <description> | The description of the API |
-V, --app-version <version> | The version of the API |
-a, --app-file <appFile> | The path to the Hono app file |
-n, --app-type <appType> | Hono app type name (default: AppType) |
-o, --output <output> | The path to the output swagger file (default: openapi.json) |
--tsconfig <tsconfig> | The path to the tsconfig file |
-h, --help | Display this message |
-v, --version | Display version number |
You can also specify options with a configuration file.
Supported configuration file formats:
- package.json (
hto
field) - hto.config.json
- hto.config.yaml
- hto.config.yml
- hto.config.js
- hto.config.cjs
- hto.config.mjs
- hto.config.ts
import { defineConfig } from "hono-typia-openapi/config";
export default defineConfig({
title: "My API",
description: "This is my API",
version: "1.0.0",
appFile: "./app.ts",
appType: "AppType",
output: "./openapi.json",
tsconfig: "./tsconfig.json",
});
Plugins of this package are created with Unplugin. You can use your favorite bundler.
Here is an example of using the Vite plugin:
// vite.config.ts
import { defineConfig } from "vite";
import HtoPlugin from "hono-typia-openapi/vite";
export default defineConfig(({ command }) => ({
plugins: [
HtoPlugin({
title: "My API",
appFile: `${__dirname}/src/app.ts`,
output: `${__dirname}/openapi.json`,
tsconfig: `${__dirname}/tsconfig.json`,
watchMode: command === "serve",
}),
],
}));
You can show the Swagger UI with @hono/swagger-ui
:
import { Hono } from "hono";
import typia, { tags } from "typia";
import { typiaValidator } from "@hono/typia-validator";
import { swaggerUI } from "@hono/swagger-ui";
interface HelloRequest {
/** Your name */
name: string & tags.MaxLength<16>;
}
const app = new Hono()
.get("/hello", (c) => {
return c.json({ message: "Hello, World!" }, 200);
})
.post(
"/hello",
typiaValidator("json", typia.createValidator<HelloRequest>()),
(c) => {
const { name } = c.req.valid("json");
return c.json({ message: `Hello, ${name}!` }, 200);
},
);
// You can strip this part in production with Dead Code Elimination and Replace Identifiers
if (process.env.NODE_ENV === "development") {
docs = (await import("fs/promises")).readFile("./openapi.json", "utf-8");
app
.get("docs", (c) => c.json(JSON.parse(docs), 200))
.get("docs/ui", swaggerUI({ url: "/docs" }));
}
export type AppType = typeof app;