ストーリー
高橋アーキテクトが首を振った。
ドキュメント自動生成
Swagger UI
// OpenAPI仕様書からインタラクティブなAPIドキュメントを生成
// Express でSwagger UIを提供する例
import swaggerUi from 'swagger-ui-express';
import YAML from 'yamljs';
const swaggerDocument = YAML.load('./openapi.yaml');
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument, {
customCss: '.swagger-ui .topbar { display: none }',
customSiteTitle: 'TaskFlow API Documentation',
}));
// → http://localhost:3000/api-docs でドキュメントが閲覧可能
// → 各エンドポイントを画面上でテスト実行できる
Redoc
// Redocはより美しいドキュメントUIを提供
// 静的HTMLとしても生成可能
// Express での設定
import redoc from 'redoc-express';
app.get('/docs', redoc({
title: 'TaskFlow API',
specUrl: '/openapi.yaml',
}));
// CLIで静的HTMLを生成
// npx @redocly/cli build-docs openapi.yaml -o docs/index.html
TypeScript型の自動生成
openapi-typescript
// OpenAPI仕様書からTypeScriptの型定義を生成
// インストールと実行
// npx openapi-typescript openapi.yaml -o src/types/api.ts
// 生成される型定義の例
// src/types/api.ts
export interface paths {
"/api/v1/users": {
get: {
parameters: {
query: {
page?: number;
perPage?: number;
};
};
responses: {
200: {
content: {
"application/json": {
data: components["schemas"]["User"][];
meta: components["schemas"]["PaginationMeta"];
};
};
};
};
};
post: {
requestBody: {
content: {
"application/json": components["schemas"]["CreateUserRequest"];
};
};
responses: {
201: {
content: {
"application/json": {
data: components["schemas"]["User"];
};
};
};
};
};
};
}
export interface components {
schemas: {
User: {
id: string;
name: string;
email: string;
role: "admin" | "member" | "viewer";
createdAt: string;
};
CreateUserRequest: {
name: string;
email: string;
password: string;
};
PaginationMeta: {
totalCount: number;
currentPage: number;
perPage: number;
totalPages: number;
};
};
}
型安全なAPIクライアント
// 生成された型を使って型安全なAPIクライアントを構築
import createClient from 'openapi-fetch';
import type { paths } from './types/api';
const client = createClient<paths>({
baseUrl: 'https://api.taskflow.example.com/v1',
});
// 型安全なAPI呼び出し
async function getUsers() {
const { data, error } = await client.GET('/api/v1/users', {
params: {
query: { page: 1, perPage: 20 },
},
});
if (error) {
console.error(error);
return;
}
// data.data は User[] 型として推論される
data.data.forEach(user => {
console.log(user.name); // 型安全
// user.foo → コンパイルエラー(存在しないプロパティ)
});
}
サーバーサイドのコード生成
バリデーションミドルウェア
// OpenAPI仕様書に基づくリクエストバリデーション
// express-openapi-validator パッケージを使用
import * as OpenApiValidator from 'express-openapi-validator';
app.use(
OpenApiValidator.middleware({
apiSpec: './openapi.yaml',
validateRequests: true, // リクエストのバリデーション
validateResponses: true, // レスポンスのバリデーション(開発時)
})
);
// バリデーションエラーのハンドリング
app.use((err: any, req: Request, res: Response, next: NextFunction) => {
if (err.status === 400 || err.status === 422) {
return res.status(err.status).json({
error: {
code: 'VALIDATION_ERROR',
message: err.message,
details: err.errors?.map((e: any) => ({
field: e.path,
message: e.message,
})),
traceId: req.id,
}
});
}
next(err);
});
// これにより、仕様書で定義した制約(minLength, pattern, enum等)が
// 自動的にバリデーションされる
コード生成ツールの比較
| ツール | 用途 | 言語 |
|---|---|---|
| openapi-typescript | TypeScript型生成 | TypeScript |
| openapi-fetch | 型安全なfetchクライアント | TypeScript |
| orval | クライアントコード生成 | TypeScript |
| openapi-generator | 多言語クライアント/サーバー生成 | 多言語 |
| express-openapi-validator | リクエスト/レスポンスバリデーション | Node.js |
| @redocly/cli | ドキュメント生成、リンティング | 任意 |
OpenAPI リンティング
// Redocly CLIで仕様書の品質チェック
// npx @redocly/cli lint openapi.yaml
// チェック内容の例:
// - 未使用のスキーマ定義
// - operationIdの欠落
// - descriptionの欠落
// - レスポンスの定義漏れ
// - セキュリティスキームの設定忘れ
// .redocly.yaml で設定
// extends:
// - recommended
// rules:
// operation-description: error
// operation-operationId: error
// no-unused-components: warn
まとめ
| ポイント | 内容 |
|---|---|
| ドキュメント生成 | Swagger UI / Redoc でインタラクティブなドキュメント |
| TypeScript型生成 | openapi-typescript で仕様から型を生成 |
| クライアント生成 | openapi-fetch で型安全なAPIクライアント |
| バリデーション | express-openapi-validator で自動バリデーション |
| リンティング | @redocly/cli で仕様書の品質チェック |
チェックリスト
- Swagger UI / Redoc によるドキュメント自動生成を理解した
- OpenAPIからTypeScript型を生成する方法を把握した
- 型安全なAPIクライアントの構築方法を理解した
- リクエスト/レスポンスの自動バリデーションの仕組みを把握した
次のステップへ
コード生成とドキュメント自動化を学びました。
次のセクションでは、API仕様ファーストの開発フローを学びます。 仕様を先に書き、実装はその仕様に従うという開発手法です。
推定読了時間: 30分