目次
- 0. バージョン選定
- 1. 開発プロセス
- 2. ファイル構成
- 3. 命名・一貫性
- 4. スキーマ設計
- 5. レスポンス・エラー
- 6. ページネーション・フィルタ
- 7. セキュリティ
- 8. ドキュメント品質(AIエージェント対応にも直結)
- 9. バージョニング・互換性
- 10. 推奨ツール
- 最小構成の例
0. バージョン選定
- 新規なら 3.1以降 を推奨。3.1でJSON Schemaとの整合、webhooks、SPDXライセンス識別子、
$refと並べたdescription記述などが追加された。 - 最新は 3.2系(3.2.0:2025年9月リリース、3.2.1あり)。構造化タグ、ストリーミング用メディアタイプ対応、任意のHTTPメソッド、OAuth2デバイスフローなどが追加。
- ツール側の対応はまだ揃っていないため、コード生成・モックなど 使うツールが対応しているバージョン に合わせるのが現実的。
1. 開発プロセス
- Design-First(スキーマ駆動):実装より先にspecを書いてレビューし、フロントとバックで契約として合意する。Code-Firstの場合も、生成されたspecはリポジトリにコミットして差分をレビュー対象にする。
- Single Source of Truth:specはGit管理し、ドキュメント・SDK・モック・バリデーションをすべてそこから生成する。
- CIでLint・破壊的変更を検知:Spectral / Redocly CLIでLint、oasdiffなどでbreaking changeを検知してPRを落とす。
2. ファイル構成
- 大きくなったら
paths/components/schemas/などに分割し、$refで参照する。配布用にはbundle(redocly bundle等)で1ファイルにまとめる。 - 再利用できるものは
componentsへ寄せる(schemas / parameters / responses / securitySchemes / examples)。 - 環境差分や公開用・社内用の出し分けは、specを複製せず Overlay仕様 で上書きする。
3. 命名・一貫性
- パスは複数形の名詞を使い、動詞は避ける:
/users/{userId}/orders - プロパティの命名規則(camelCase / snake_case)はAPI全体で統一する。
operationIdは全オペレーションに必須。一意で、生成コードのメソッド名として読める名前にする(listUsers,createOrder)。tagsで論理的にグルーピングする(ドキュメントやSDKの単位になる)。
4. スキーマ設計
requiredを明示し、additionalPropertiesの扱いも意図的に決める。format(date-time,uuid,email)、minLength/maxLength、pattern、enum、minimum/maximumで制約を具体的に書く。- リクエストとレスポンスでモデルを分けるか、
readOnly/writeOnlyを使う(idやcreatedAtはreadOnly、passwordはwriteOnly)。 - nullableは3.1以降なら
type: [string, "null"]と書く(3.0のnullable: trueは廃止)。 - ポリモーフィズムは
oneOfとdiscriminatorの組み合わせにする。anyOfの乱用は生成コードを壊しやすい。 - インラインスキーマを避けて名前付きの
components/schemasにすると、生成される型名が安定する。
5. レスポンス・エラー
- 成功系だけでなく 4xx/5xxも全部定義 する(400, 401, 403, 404, 409, 422, 429, 500など)。
- エラー形式は RFC 9457(Problem Details,
application/problem+json) に統一する。 - 共通エラーは
components/responsesにまとめて$refで再利用する。 201にはLocationヘッダ、429にはRetry-Afterなど、ヘッダも記述する。
6. ページネーション・フィルタ
- ページネーション方式(cursor推奨、またはoffset)をAPI全体で統一し、共通のparametersとレスポンスのラッパースキーマとして定義する。
- ソートやフィルタのクエリパラメータ名の規約も決めておく(
sort=-createdAt、filter[status]=activeなど)。
7. セキュリティ
securitySchemesを定義し、トップレベルのsecurityでデフォルトを適用する。公開エンドポイントだけsecurity: []で外す。- OAuth2なら、オペレーションごとに必要なスコープを明記する。
- 機密値をexampleに入れない。
serversに本番の内部URLを書かない。
8. ドキュメント品質(AIエージェント対応にも直結)
summaryは短く、descriptionには振る舞い・副作用・制約を書く(CommonMark可)。examplesを充実 させる。モックサーバ(Prism等)、テスト、LLMのツール利用の精度に効く。- OpenAPI InitiativeもLLMを新しい種類のAPIクライアントと捉え、「agent-ready」なOpenAPI文書に必要なメタデータを検討中。specからMCPサーバを生成する場合は、descriptionとoperationIdの質がそのままツール選択の精度になる。
9. バージョニング・互換性
info.versionはAPI契約のバージョンを表し、OpenAPI仕様のバージョン(openapi:)とは別物。- 破壊的変更はURL(
/v2)やヘッダでメジャーバージョンを分ける。非推奨にするものはdeprecated: trueとSunsetヘッダで段階的に廃止する。 - フィールドの追加は後方互換。クライアント側は未知フィールドを無視する前提で設計する。
10. 推奨ツール
| 用途 | ツール例 |
|---|---|
| Lint / ルール強制 | Spectral, Redocly CLI, Vacuum |
| 差分・破壊的変更検知 | oasdiff |
| ドキュメント | Redoc, Scalar, Swagger UI |
| モック | Prism |
| コード生成 | openapi-generator, openapi-typescript, orval |
| Rails | rswag, committee(リクエスト/レスポンスのspec準拠テスト) |
最小構成の例
openapi: 3.1.0
info:
title: Example API
version: 1.2.0
servers:
- url: https://api.example.com/v1
security:
- bearerAuth: []
paths:
/users/{userId}:
get:
operationId: getUser
summary: ユーザーを1件取得
tags: [Users]
parameters:
- $ref: '#/components/parameters/UserId'
responses:
'200':
description: OK
content:
application/json:
schema: { $ref: '#/components/schemas/User' }
'404': { $ref: '#/components/responses/NotFound' }
components:
securitySchemes:
bearerAuth: { type: http, scheme: bearer, bearerFormat: JWT }
parameters:
UserId:
name: userId
in: path
required: true
schema: { type: string, format: uuid }
schemas:
User:
type: object
required: [id, email]
properties:
id: { type: string, format: uuid, readOnly: true }
email: { type: string, format: email }
nickname: { type: [string, "null"], maxLength: 50 }
Problem:
type: object
properties:
type: { type: string, format: uri }
title: { type: string }
status: { type: integer }
detail: { type: string }
instance: { type: string, format: uri }
responses:
NotFound:
description: Not Found
content:
application/problem+json:
schema: { $ref: '#/components/schemas/Problem' }