OpenAPI ドキュメントの追加¶
Hono REST テンプレートには /docs の Scalar UI と /openapi.json の OpenAPI 3.1 仕様が同梱されており、@hono/zod-openapi によって動作しています。このレシピでは、各構成要素がどう連携しているか、そして生成される仕様をどう拡張するかを説明します。
提供されるもの¶
src/ZodOpenapi.res—@hono/zod-openapiの ReScript バインディングsrc/Scalar.res—@scalar/hono-api-referenceのバインディングsrc/Server.res—/openapi.jsonと/docsの配線src/Routes/Users.res— 仕様に公開された users CRUD
pnpm dev の後に http://localhost:3000/docs を開くと、インタラクティブな UI を確認できます。
全体の配線¶
Zod schema ──► @hono/zod-openapi createRoute ──► app.openapi(route, handler)
│
├─► /openapi.json (spec)
└─► Route handler (validated input/output)
/openapi.json ──► Scalar.apiReference ──► /docs (interactive UI)
Zod スキーマの定義¶
// src/Schemas.res
let createUser = ZodOpenapi.object({
"name": ZodOpenapi.string(~minLength=1, ()),
"email": ZodOpenapi.string(~format="email", ()),
})
let user = ZodOpenapi.object({
"id": ZodOpenapi.number(),
"name": ZodOpenapi.string(),
"email": ZodOpenapi.string(~format="email", ()),
})
ルートにアタッチする¶
let route = ZodOpenapi.createRoute({
"method": "post",
"path": "/users",
"request": {
"body": {
"content": {
"application/json": {"schema": Schemas.createUser},
},
},
},
"responses": {
"201": {
"description": "Created",
"content": {
"application/json": {"schema": Schemas.user},
},
},
"400": {"description": "Validation error"},
},
})
app->ZodOpenapi.openapi(route, async ctx => {
let body = ctx->ZodOpenapi.validBody
/* body is typed from Schemas.createUser */
})
API を記述する¶
Scalar UI にタイトル、説明、サーバー一覧を表示させるためのメタデータを追加します:
// src/Server.res
app->ZodOpenapi.doc("/openapi.json", {
"openapi": "3.1.0",
"info": {
"title": "My API",
"version": "1.0.0",
"description": "User management service.",
},
"servers": [
{"url": "http://localhost:3000", "description": "Local"},
{"url": "https://api.example.com", "description": "Production"},
],
})
セキュリティ¶
Bearer トークン認証を仕様に組み込みます:
app->ZodOpenapi.registerComponent("securitySchemes", "BearerAuth", {
"type": "http",
"scheme": "bearer",
"bearerFormat": "JWT",
})
let protectedRoute = ZodOpenapi.createRoute({
/* ... */
"security": [{"BearerAuth": []}],
})
Scalar UI は "Authorize" ボタンを表示し、訪問者がトークンを貼り付けられるようにします。
仕様のエクスポート¶
curl http://localhost:3000/openapi.json > openapi.json で仕様をディスクに書き出せます。これを CI に組み込んで仕様がコミット間で安定していることを検証したり、クライアントジェネレータ (openapi-generator、orval、@hey-api/openapi-ts) に渡したりできます。
UI の切り替え¶
Scalar がデフォルトですが、/openapi.json の仕様は任意の OpenAPI レンダラーで使用できます:
src/Server.res の Scalar.apiReference を同等のハンドラに置き換えてください。
よくある落とし穴¶
ルートが
/docsに表示されない —app.get(...)ではなくapp.openapi(route, handler)を使用してください。通常の Hono ルートは仕様に現れません。Scalar UI が空白 — ブラウザコンソールを確認してください。多くの場合、
/openapi.jsonが JSON ではなく HTML (エラーページ) を返しています。直接アクセスして実際のエラーを確認してください。Zod スキーマの不一致 — レスポンスハンドラが Zod で変換できない形状を返すと、バリデーションエラーで 500 になります。実行時の形状に一致させるには
ZodOpenapi.string(~format="email", ())のようなヘルパーを使ってください。