JSON Schema 入門:データ形状をバリデーションする標準

約5分

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"
}

formatemailuridate-timeuuid など事前定義された形式。バリデータによって対応状況が違うため、規格通りの動作は保証されない。

数値の制約

{
	"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 データの構造を定義する標準仕様
  • typepropertiesrequiredadditionalProperties が基本
  • $ref で定義を再利用、oneOf / anyOf で論理結合
  • API 仕様・設定ファイル・フォーム検証で広く使われる

JSON データが特定のスキーマに準拠しているか試したいときは、本サイトの JSON バリデータが使えます。スキーマと検証対象を貼り付けて結果を確認できます。