APIドキュメント
ルール
- OpenAPI 3.1仕様を唯一の真実の情報源とする — コードから生成し、手動で記述しない
- ZodスキーマからOpenAPIへ:
zod-openapiまたは@asteasolutions/zod-to-openapiを使用 — 一度定義すれば、バリデーションとドキュメント作成が可能
- インタラクティブドキュメント: Scalar(モダンで高速)またはSwagger UI —
/docsまたは/api-docsで提供
- すべてのエンドポイントに以下を必須とする: 要約、説明、リクエストボディスキーマ、すべてのレスポンスコードとその例
- 全エンドポイントにリクエスト/レスポンスの例 — 現実的なデータを使用し、
"string"のようなプレースホルダーは避ける
- バージョン管理戦略: 破壊的変更にはURLパス(
/api/v1/、/api/v2/) — ヘッダーベースのバージョン管理よりもシンプル
- エラーレスポンス: すべてのエラー形式を一貫して文書化 —
{ error: string, code: string, details?: object }
- 認証: セキュリティスキームセクションに認証方式(Bearerトークン、APIキー)を文書化
- エンドポイントをリソースごとにグループ化:
/users、/products、/orders — ドキュメントUIでのグループ化にタグを使用
パターン
import { z } from "zod";
import { extendZodWithOpenApi } from "@asteasolutions/zod-to-openapi";
extendZodWithOpenApi(z);
const UserSchema = z.object({
id: z.string().uuid().openapi({ example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890" }),
name: z.string().openapi({ example: "Jane Smith" }),
email: z.string().email().openapi({ example: "[email protected]" }),
}).openapi("User");
const CreateUserSchema = UserSchema.omit({ id: true }).openapi("CreateUser");
registry.registerPath({
method: "post",
path: "/api/v1/users",
summary: "ユーザーを作成",
request: { body: { content: { "application/json": { schema: CreateUserSchema } } } },
responses: {
201: { description: "ユーザー作成完了", content: { "application/json": { schema: UserSchema } } },
400: { description: "バリデーションエラー" },
},
});
避けるべきこと
- OpenAPI YAMLを手動で記述 — Zodスキーマまたはルート定義から生成する
- エラーレスポンスのドキュメント化漏れ — 400、401、403、404、500を必ず文書化
"string"や0のような汎用的な例 — 実際のデータ構造を示す現実的な値を使用
- 実装から乖離したドキュメント — バリデーションに使用するのと同じスキーマから仕様を生成する