OpenAPI 仕様の基礎
OpenAPI 仕様(OAS)は、RESTful API を記述するための標準フォーマットです。
OpenAPI 仕様により、開発者は API の構造、パラメータ、レスポンスなどの情報を機械可読な形式で定義できます。
OpenAPI 仕様は当初 Swagger 仕様と呼ばれていましたが、後に OpenAPI Initiative に寄贈され、OpenAPI に改名されました。
OpenAPI 仕様の主な役割は次のとおりです。
- API の標準化されたドキュメントの提供
- API の自動化テストのサポート
- クライアント SDK の生成
- フロントエンドとバックエンドの分離開発の促進
OpenAPI には現在、広く使用されている主要なバージョンが2つあります。
- OpenAPI 2.0(旧 Swagger 2.0)
- OpenAPI 3.x(最新の安定版)
新規プロジェクトでは、より多くの機能と改善が提供されている OpenAPI 3.x バージョンの使用を推奨します。
OpenAPI 仕様の構造
OpenAPI ドキュメントは通常、YAML または JSON 形式で記述されます。
以下は基本的な OpenAPI ドキュメントの構造です。
例
info:
title: サンプル API # API の名称
description: これはサンプルの API ドキュメントです
version: 1.0.0 # API バージョン
servers:
- url: https://api.example.com/v1 # API サーバーのアドレス
description: 本番環境
- url: https://dev-api.example.com/v1
description: 開発環境
paths: # API パスの定義
/users: # エンドポイントのパス
get: # HTTP メソッド
summary: すべてのユーザーを取得
description: システム内のすべてのユーザーリストを返します
operationId: getUsers
tags:
- users # グループラベル
parameters: # リクエストパラメータ
- name: limit
in: query
description: 返される結果の件数制限
schema:
type: integer
default: 20
responses: # レスポンス定義
'200': # HTTP ステータスコード
description: 成功時にユーザーリストを返します
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'
'400':
description: 不正なリクエストパラメータ
components: # 再利用可能なコンポーネント
schemas: # データモデル定義
User:
type: object
properties:
id:
type: integer
format: int64
name:
type: string
email:
type: string
format: email
required:
- id
- name
OpenAPI の核心概念の詳細
1. ドキュメントメタデータ (info)
info セクションには、タイトル、説明、バージョンなど API の基本情報が含まれます。
例
title: ユーザー管理 API
description: システム内のユーザー情報を管理するための API
version: 1.0.0
contact:
name: API サポートチーム
email: [email protected]
license:
name: Apache 2.0
url: https://www.apache.org/licenses/LICENSE-2.0.html
2. サーバー情報 (servers)
servers セクションは、利用可能な API サーバーのリストを定義します。
例
- url: https://api.example.com/v1
description: 本番環境
- url: https://staging-api.example.com/v1
description: テスト環境
3. パス (paths)
paths セクションは、API のすべてのエンドポイントと、それらがサポートする HTTP メソッドを定義します。
例
/users:
get:
# ユーザーリストを取得
post:
# 新規ユーザーを作成
/users/{userId}:
get:
# 特定のユーザーを取得
put:
# ユーザーを更新
delete:
# ユーザーを削除
4. 操作 (operations)
各パスの HTTP メソッドが 1 つの API 操作を定義します。
例
/users/{userId}:
get:
summary: ユーザー詳細を取得
description: ユーザー ID に基づいてユーザーの詳細情報を取得します
operationId: getUserById
tags:
- users
parameters:
- name: userId
in: path
required: true
description: ユーザー ID
schema:
type: integer
responses:
'200':
description: ユーザー情報の取得に成功
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'404':
description: ユーザーが存在しません
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
5. パラメータ (parameters)
パラメータは複数の場所に定義できます。
例
- name: userId
in: path # パスパラメータ
required: true
schema:
type: integer
- name: filter
in: query # クエリパラメータ
schema:
type: string
- name: X-API-Key
in: header # リクエストヘッダーパラメータ
schema:
type: string
- name: trace
in: cookie # Cookie パラメータ
schema:
type: string
6. リクエストボディ (requestBody)
POST、PUT などのメソッドのリクエストボディを定義します。
例
description: ユーザーデータ
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/User'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/UserForm'
7. レスポンス (responses)
各操作で発生し得るレスポンスを定義します。
例
'200':
description: 操作成功
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessResponse'
'400':
description: リクエストパラメータのエラー
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
8. コンポーネント (components)
components セクションは、API ドキュメント全体で再利用できる要素を格納するために使用します。
例
schemas:
User:
type: object
properties:
id:
type: integer
name:
type: string
email:
type: string
format: email
roles:
type: array
items:
type: string
enum: [admin, user, editor]
required:
- name
Error:
type: object
properties:
code:
type: integer
message:
type: string
required:
- code
- message
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: X-API-Key
OAuth2:
type: oauth2
flows:
implicit:
authorizationUrl: https://example.com/oauth/authorize
scopes:
read: 読み取り権限
write: 書き込み権限
9. データモデル (schemas)
API で使用されるデータ構造を定義します。
例
Product:
type: object
properties:
id:
type: integer
name:
type: string
maxLength: 100
price:
type: number
format: float
minimum: 0
category:
type: string
enum: [electronics, books, clothing]
10. セキュリティ (security)
API の認証と認可の方法を定義します。
例
- ApiKeyAuth: []
- OAuth2: [read, write]
完全な OpenAPI ドキュメントの例を作成する
以下は、より完全な電子商取引 API の例です。
例
info:
title: 電子商取引 API
description: オンラインストアの商品と注文を管理するための API
version: 1.0.0
contact:
name: APIサポートチーム
email: [email protected]
url: https://api.example.com/support
license:
name: MIT
url: https://opensource.org/licenses/MIT
servers:
- url: https://api.example.com/v1
description: 本番環境
- url: https://dev-api.example.com/v1
description: 開発環境
tags:
- name: products
description: 製品関連操作
- name: orders
description: 注文関連操作
- name: users
description: ユーザー関連操作
paths:
/products:
get:
summary: 製品リストの取得
description: 利用可能なすべての製品のリストを返します。ページネーションとフィルタリングに対応します。
operationId: getProducts
tags:
- products
parameters:
- name: category
in: query
description: 製品カテゴリでフィルタリング
schema:
type: string
- name: page
in: query
description: ページ番号
schema:
type: integer
default: 1
- name: limit
in: query
description: 1ページあたりの件数
schema:
type: integer
default: 20
responses:
'200':
description: 製品リストの取得成功
content:
application/json:
schema:
type: object
properties:
total:
type: integer
products:
type: array
items:
$ref: '#/components/schemas/Product'
'400':
description: パラメータエラー
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
post:
summary: 新規製品の作成
description: 新しい製品情報を作成します
operationId: createProduct
tags:
- products
security:
- ApiKeyAuth: []
- OAuth2: [write]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ProductCreate'
responses:
'201':
description: 製品の作成が成功しました
content:
application/json:
schema:
$ref: '#/components/schemas/Product'
'400':
description: リクエストデータが無効です
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: 未認証
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/products/{productId}:
get:
summary: 製品詳細の取得
description: IDに基づいて特定の製品の詳細情報を取得します
operationId: getProductById
tags:
- products
parameters:
- name: productId
in: path
required: true
description: 製品ID
schema:
type: integer
responses:
'200':
description: 製品情報の取得成功
content:
application/json:
schema:
$ref: '#/components/schemas/Product'
'404':
description: 製品が存在しません
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
put:
summary: 製品の更新
description: 特定の製品の情報を更新します
operationId: updateProduct
tags:
- products
security:
- ApiKeyAuth: []
- OAuth2: [write]
parameters:
- name: productId
in: path
required: true
description: 製品ID
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ProductUpdate'
responses:
'200':
description: 製品の更新が成功しました
content:
application/json:
schema:
$ref: '#/components/schemas/Product'
'400':
description: リクエストデータが無効です
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: 未認証
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: 製品が存在しません
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
delete:
summary: 製品の削除
description: 特定の製品を削除します
operationId: deleteProduct
tags:
- products
security:
- ApiKeyAuth: []
- OAuth2: [write]
parameters:
- name: productId
in: path
required: true
description: 製品ID
schema:
type: integer
responses:
'204':
description: 製品の削除が成功しました
'401':
description: 未認証
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: 製品が存在しません
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/orders:
get:
summary: 注文リストの取得
description: すべての注文のリストを返します。ページネーションとフィルタリングに対応します。
operationId: getOrders
tags:
- orders
security:
- ApiKeyAuth: []
- OAuth2: [read]
parameters:
- name: status
in: query
description: 注文ステータスでフィルタリング
schema:
type: string
enum: [pending, processing, shipped, delivered, cancelled]
- name: page
in: query
description: ページ番号
schema:
type: integer
default: 1
- name: limit
in: query
description: 1ページあたりの件数
schema:
type: integer
default: 20
responses:
'200':
description: 注文リストの取得成功
content:
application/json:
schema:
type: object
properties:
total:
type: integer
orders:
type: array
items:
$ref: '#/components/schemas/Order'
'401':
description: 未認証
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
post:
summary: 新規注文の作成
description: 新しい注文を作成します
operationId: createOrder
tags:
- orders
security:
- ApiKeyAuth: []
- OAuth2: [write]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/OrderCreate'
responses:
'201':
description: 注文の作成が成功しました
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
'400':
description: リクエストデータが無効です
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: 未認証
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
components:
schemas:
Product:
type: object
properties:
id:
type: integer
format: int64
readOnly: true
name:
type: string
maxLength: 100
description:
type: string
price:
type: number
format: float
minimum: 0
category:
type: string
enum: [electronics, books, clothing, food]
inStock:
type: boolean
default: true
createdAt:
type: string
format: date-time
readOnly: true
updatedAt:
type: string
format: date-time
readOnly: true
required:
- name
- price
- category
ProductCreate:
type: object
properties:
name:
type: string
maxLength: 100
description:
type: string
price:
type: number
format: float
minimum: 0
category:
type: string
enum: [electronics, books, clothing, food]
inStock:
type: boolean
default: true
required:
- name
- price
- category
ProductUpdate:
type: object
properties:
name:
type: string
maxLength: 100
description:
type: string
price:
type: number
format: float
minimum: 0
category:
type: string
enum: [electronics, books, clothing, food]
inStock:
type: boolean
Order:
type: object
properties:
id:
type: integer
format: int64
readOnly: true
userId:
type: integer
format: int64
items:
type: array
items:
$ref: '#/components/schemas/OrderItem'
totalAmount:
type: number
format: float
readOnly: true
status:
type: string
enum: [pending, processing, shipped, delivered, cancelled]
default: pending
shippingAddress:
$ref: '#/components/schemas/Address'
createdAt:
type: string
format: date-time
readOnly: true
updatedAt:
type: string
format: date-time
readOnly: true
required:
- userId
- items
- shippingAddress
OrderCreate:
type: object
properties:
userId:
type: integer
format: int64
items:
type: array
items:
$ref: '#/components/schemas/OrderItem'
shippingAddress:
$ref: '#/components/schemas/Address'
required:
- userId
- items
- shippingAddress
OrderItem:
type: object
properties:
productId:
type: integer
format: int64
quantity:
type: integer
minimum: 1
default: 1
unitPrice:
type: number
format: float
readOnly: true
required:
- productId
- quantity
Address:
type: object
properties:
street:
type: string
city:
type: string
state:
type: string
zipCode:
type: string
country:
type: string
required:
- street
- city
- state
- zipCode
- country
Error:
type: object
properties:
code:
type: integer
message:
type: string
required:
- code
- message
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: X-API-Key
OAuth2:
type: oauth2
flows:
implicit:
authorizationUrl: https://example.com/oauth/authorize
scopes:
read: 読み取り権限
write: 書き込み権限
security:
- ApiKeyAuth: []
OpenAPI 仕様の基本構文
OpenAPI仕様は2つの形式をサポートしています:
- YAML(推奨)
- JSON
YAML 形式の例
例
info:
title: ペットショップAPI
version: 1.0.0
paths:
/pets:
get:
summary: すべてのペットを一覧表示
responses:
'200':
description: ペットリストの取得成功
JSON 形式の例
例
"info": {
"title": "ペットショップAPI",
"version": "1.0.0"
},
"paths": {
"/pets": {
"get": {
"summary": "すべてのペットを一覧表示",
"responses": {
"200": {
"description": "ペットリストの取得成功"
}
}
}
}
}
}
OpenAPI 仕様の使用方法
1. OpenAPI ドキュメントの作成と編集
以下のツールを使用してOpenAPIドキュメントを作成および編集できます:
- Swagger Editor:オンラインエディタ。リアルタイムプレビューと検証を提供します
- Stoplight Studio:ビジュアルAPI設計ツール
- VS Code + OpenAPIプラグイン:統合開発環境での編集
2. ドキュメント生成
OpenAPI仕様を使用すると、美しいAPIドキュメントを自動生成できます。一般的なツールは次のとおりです:
- Swagger UI:インタラクティブなAPIドキュメントを生成
- ReDoc:レスポンシブでカスタマイズ可能なドキュメントを提供
- Slate:エレガントな静的ドキュメントを生成
3. コード生成
OpenAPIは多言語のクライアントおよびサーバーコードを自動生成できます:
- OpenAPI Generator:40以上のプログラミング言語をサポート
- Swagger Codegen:クライアントおよびサーバーコードを生成
- NSwag:.NETエコシステム向けのコードジェネレーター
4. API テストとモック
OpenAPI仕様は次の用途にも使用できます:
- 自動化テスト:Postman、SoapUIなどのツールを使用
- APIモック:Prism、MicrocksなどはOpenAPI仕様に基づいてAPIをモックできます
ベストプラクティス
1. 設計原則
- エンドポイントの命名規則を統一する
- 適切なHTTPメソッドとステータスコードを使用する
- 明確なURLパス構造を設計する
2. ドキュメントの推奨事項
- 詳細な説明と例を提供する
- タグを使用してAPIをグループ化する
- 必須パラメータを明確に指定する
3. バージョン管理戦略
- URLにバージョン番号を含める(
/v1/users) - リクエストヘッダーでバージョンを指定する(
Accept: application/vnd.example.v1+json) - OpenAPIドキュメントにバージョン情報を明記する
よくある質問と回答
1. OpenAPI と Swagger の違いは?
SwaggerはOpenAPI仕様の前身です。2016年にSwagger仕様はLinux Foundationに寄贈され、OpenAPI仕様に改名されました。現在「Swagger」は通常、OpenAPI仕様を中心に構築されたツール群を指します。
2. OpenAPI 2.0 と 3.x の主な違いは?
OpenAPI 3.xでは多くの新機能が導入されました。例えば:
- 改善されたコンポーネント再利用
- より柔軟なリクエストボディ定義
- より強力なセキュリティ定義
- 改善されたJSON Schemaサポート
- links(リンク)とcallbacks(コールバック)のサポート
3. 認証と認可をどのように扱うか?
OpenAPIは複数のセキュリティメカニズムをサポートしています:
- APIキー
- HTTP基本認証
- OAuth2.0
- OpenID Connect
- カスタムヘッダー認証
学習リソース
- 公式ドキュメント:OpenAPI Initiative
- ツール:
- 学習リソース: