JSON Schema 入門:データ形状をバリデーションする標準
JSON データの「形状」を定義してバリデーションする標準が JSON Schema です。OpenAPI、各種設定ファイル、フォーム検証など、さまざまな場面で使われます。本記事では基本の書き方と、よくある罠を整理します。
JSON Schema とは
JSON Schema は JSON でJSON データの構造を記述する仕様(IETF Draft)。
例:
{
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "integer", "minimum": 0 }
},
"required": ["name"]
} このスキーマに対して { "name": "Alice", "age": 30 } は valid、{ "age": -5 } は invalid(required 違反 + minimum 違反)。
基本のキーワード
型(type)
{ "type": "string" }
{ "type": "integer" }
{ "type": "number" }
{ "type": "boolean" }
{ "type": "array" }
{ "type": "object" }
{ "type": "null" } 複数許容も可:
{ "type": ["string", "null"] } オブジェクトのプロパティ
{
"type": "object",
"properties": {
"id": { "type": "integer" },
"name": { "type": "string" }
},
"required": ["id", "name"],
"additionalProperties": false
} additionalProperties: false を入れると、定義していないキーは拒否されます。これを忘れると未知のキーがすべて許容されてしまうので注意。
配列
{
"type": "array",
"items": { "type": "integer" },
"minItems": 1,
"maxItems": 100
} 文字列の制約
{
"type": "string",
"minLength": 3,
"maxLength": 50,
"pattern": "^[A-Z][a-z]+$",
"format": "email"
} format は email、uri、date-time、uuid など事前定義された形式。バリデータによって対応状況が違うため、規格通りの動作は保証されない。
数値の制約
{
"type": "integer",
"minimum": 0,
"maximum": 100,
"exclusiveMinimum": 0
} 高度な機能
enum:許可された値の列挙
{ "enum": ["red", "green", "blue"] } 文字列だけでなく任意の値を許容。
oneOf / anyOf / allOf:論理結合
{
"oneOf": [{ "type": "string" }, { "type": "integer" }]
} oneOf:ちょうど 1 つにマッチanyOf:1 つ以上にマッチallOf:すべてにマッチ
$ref:定義の再利用
{
"$defs": {
"address": {
"type": "object",
"properties": {
"street": { "type": "string" },
"city": { "type": "string" }
}
}
},
"type": "object",
"properties": {
"shipping": { "$ref": "#/$defs/address" },
"billing": { "$ref": "#/$defs/address" }
}
} $ref で定義を再利用。OpenAPI では components.schemas 配下に共通スキーマを定義してまとめて参照します。
利用シーン
1. API 仕様(OpenAPI / Swagger)
OpenAPI スキーマは内部的に JSON Schema を採用。リクエスト・レスポンスの形状を定義し、ツールでドキュメント生成・モックサーバー作成・クライアント生成が可能。
2. 設定ファイル
VS Code、ESLint、Prettier などの設定ファイルは JSON Schema を公開しており、エディタが自動補完とバリデーションを提供。
3. フォームバリデーション
サーバー側でリクエストボディを検証する際、ライブラリ(Ajv、Joi に変換、Zod など)に JSON Schema を渡してバリデーション。
4. データベースのスキーマ補完
Postgres の JSONB カラムに JSON Schema 制約を CHECK 制約として実装する例も。
実装でハマるポイント
1. additionalProperties を忘れない
{
"properties": {
"name": { "type": "string" }
}
} これは「name プロパティは文字列であるべき」と言うだけで、他のプロパティは何でも許容。typo した未知のキーが通ってしまう。additionalProperties: false で厳格化する。
2. integer vs number
number は浮動小数を許容、integer は整数のみ。{"type": "integer"} に 1.0 が来た場合の挙動はバリデータごとに違う。
3. format のサポートばらつき
format: "email" の検証ロジックは厳密に決まっておらず、バリデータごとに正規表現が違う。本格的にメールアドレスを検証したいなら別途ライブラリを使う方が安全。
4. nullable の表現
OpenAPI 3.0 は nullable: true、JSON Schema は type: ["string", "null"]。混同しやすい。
まとめ
- JSON Schema は JSON データの構造を定義する標準仕様
type、properties、required、additionalPropertiesが基本$refで定義を再利用、oneOf/anyOfで論理結合- API 仕様・設定ファイル・フォーム検証で広く使われる
JSON データが特定のスキーマに準拠しているか試したいときは、本サイトの JSON バリデータが使えます。スキーマと検証対象を貼り付けて結果を確認できます。