ストーリー
高橋アーキテクトがバリデーションエラーのログを見せた。
データ型と制約
基本データ型
# 文字列
name:
type: string
minLength: 1
maxLength: 100
example: "田中太郎"
# 数値
age:
type: integer
minimum: 0
maximum: 150
example: 25
price:
type: number
format: double
minimum: 0
exclusiveMinimum: true
example: 1500.50
# 真偽値
isActive:
type: boolean
default: true
# 日付・時刻
createdAt:
type: string
format: date-time
example: "2025-01-15T09:00:00Z"
birthDate:
type: string
format: date
example: "1990-05-15"
文字列の制約
# 正規表現パターン
zipCode:
type: string
pattern: "^\\d{3}-\\d{4}$"
example: "100-0001"
phoneNumber:
type: string
pattern: "^0\\d{1,4}-\\d{1,4}-\\d{4}$"
example: "03-1234-5678"
# format による制約
email:
type: string
format: email
example: "user@example.com"
url:
type: string
format: uri
example: "https://example.com"
uuid:
type: string
format: uuid
example: "550e8400-e29b-41d4-a716-446655440000"
列挙型(Enum)
status:
type: string
enum: [todo, in_progress, in_review, done]
description: |
タスクのステータス:
* `todo` - 未着手
* `in_progress` - 進行中
* `in_review` - レビュー中
* `done` - 完了
priority:
type: string
enum: [low, medium, high, critical]
default: medium
複合型の定義
オブジェクトとネスト
components:
schemas:
Task:
type: object
required: [id, title, status, createdAt]
properties:
id:
type: string
example: "tsk_789"
title:
type: string
minLength: 1
maxLength: 200
description:
type: string
maxLength: 5000
nullable: true
status:
type: string
enum: [todo, in_progress, in_review, done]
priority:
type: string
enum: [low, medium, high, critical]
default: medium
assignee:
$ref: "#/components/schemas/UserSummary"
labels:
type: array
items:
$ref: "#/components/schemas/Label"
maxItems: 10
dueDate:
type: string
format: date-time
nullable: true
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
UserSummary:
type: object
required: [id, name]
properties:
id:
type: string
name:
type: string
Label:
type: object
required: [id, name, color]
properties:
id:
type: string
name:
type: string
color:
type: string
pattern: "^#[0-9a-fA-F]{6}$"
配列の制約
tags:
type: array
items:
type: string
minLength: 1
maxLength: 50
minItems: 0
maxItems: 20
uniqueItems: true
example: ["frontend", "urgent", "bug"]
高度なスキーマ機能
oneOf / anyOf / allOf
# allOf: 複数のスキーマを結合(AND)
CreateTaskRequest:
allOf:
- $ref: "#/components/schemas/TaskBase"
- type: object
required: [title]
properties:
assigneeId:
type: string
# oneOf: いずれか1つに合致(XOR)
NotificationTarget:
oneOf:
- $ref: "#/components/schemas/EmailTarget"
- $ref: "#/components/schemas/SlackTarget"
- $ref: "#/components/schemas/WebhookTarget"
discriminator:
propertyName: type
mapping:
email: "#/components/schemas/EmailTarget"
slack: "#/components/schemas/SlackTarget"
webhook: "#/components/schemas/WebhookTarget"
# anyOf: 1つ以上に合致(OR)
SearchResult:
anyOf:
- $ref: "#/components/schemas/UserResult"
- $ref: "#/components/schemas/TaskResult"
再利用可能なレスポンス
components:
responses:
NotFound:
description: "リソースが見つかりません"
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
example:
error:
code: "NOT_FOUND"
message: "指定されたリソースが見つかりません"
traceId: "req_abc123"
ValidationError:
description: "バリデーションエラー"
content:
application/json:
schema:
$ref: "#/components/schemas/ValidationErrorResponse"
Unauthorized:
description: "認証エラー"
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
example:
error:
code: "UNAUTHENTICATED"
message: "認証が必要です"
traceId: "req_def456"
schemas:
ErrorResponse:
type: object
required: [error]
properties:
error:
type: object
required: [code, message, traceId]
properties:
code:
type: string
message:
type: string
traceId:
type: string
ValidationErrorResponse:
type: object
required: [error]
properties:
error:
type: object
required: [code, message, details, traceId]
properties:
code:
type: string
example: "VALIDATION_ERROR"
message:
type: string
details:
type: array
items:
type: object
properties:
field:
type: string
message:
type: string
traceId:
type: string
まとめ
| ポイント | 内容 |
|---|---|
| 基本データ型 | string, integer, number, boolean + format |
| 文字列制約 | minLength, maxLength, pattern, format |
| 数値制約 | minimum, maximum, exclusiveMinimum |
| 列挙型 | enum で許容値を限定 |
| 複合型 | allOf(結合), oneOf(排他), anyOf(論理和) |
| 再利用 | $ref でスキーマ・レスポンスを共有 |
チェックリスト
- 基本データ型と制約(minLength, pattern, enum等)を使いこなせる
- ネストされたオブジェクトのスキーマを定義できる
- allOf, oneOf, anyOf の違いと使い分けを理解した
- 再利用可能なレスポンス定義のパターンを把握した
次のステップへ
スキーマ定義とバリデーションを学びました。
次のセクションでは、OpenAPIからのコード生成とドキュメント自動化を学びます。 仕様書を書くだけで、実装の大部分が自動化される世界を体験しましょう。
推定読了時間: 30分