JSON Schema 検証とは?
JSON Schema 検証とは、JSON ドキュメントが JSON Schema で定義された構造的・値的制約に適合しているかどうかを確認するプロセスです。スキーマ自体も JSON ドキュメントであり、データの期待される形状を記述します。どのプロパティが必須か、どの型でなければならないか、数値の許容範囲、文字列のパターン、配列の長さなどが含まれます。JSON Schema の仕様は json-schema.org で管理されており、一連の IETF ドラフトとして公開されています。Draft 7 と Draft 2020-12 が最も広く採用されています。
単純な JSON 検証が構文のみをチェックする(括弧が対応しているか?文字列はクォートされているか?)のに対し、スキーマ検証はさらに踏み込みます。この API のレスポンスには常に整数の「id」フィールドが含まれているか?「status」フィールドは3つの許可された値のうちの1つか?ネストされたオブジェクトは正しい形状になっているか?このような構造的検証は、構文チェックでは見逃すバグを捕捉します。構文的に有効な JSON でも、アプリケーションにとって意味的に間違っている場合があるためです。
JSON Schema は OpenAPI/Swagger 定義、設定ファイルの検証、フォームバリデーション、データベースのドキュメント制約、自動テストに利用されています。Ajv(JavaScript)、jsonschema(Python)、check-jsonschema(CLI)などのツールが仕様を実装しており、プログラムからデータを検証できます。このオンラインバリデーターでは、スキーマとデータドキュメントの両方を貼り付けて、ライブラリをインストールすることなく即座に適合性を確認できます。
オンライン JSON Schema バリデーターを使う理由
スキーマの作成や検証エラーの手動デバッグは時間がかかります。オンライン JSON Schema バリデーターを使えば、データがスキーマに適合しているかどうかを即座に確認でき、失敗した正確なプロパティを示す明確なエラーメッセージが得られます。
JSON Schema 検証のユースケース
JSON Schema キーワードリファレンス
JSON Schema はキーワードで構成されており、それぞれが検証対象のデータに対して制約を課します。以下の表は Draft 7 以降でよく使用されるキーワードをまとめたものです。すべてのキーワードは同じスキーマオブジェクト内で組み合わせて使用できます。
| キーワード | 目的 | 使用例 |
|---|---|---|
| type | Restricts the data type | "type": "string" |
| properties | Defines expected object keys and their schemas | "properties": { "name": { "type": "string" } } |
| required | Lists mandatory properties | "required": ["id", "name"] |
| items | Schema for array elements | "items": { "type": "number" } |
| enum | Restricts value to a fixed set | "enum": ["active", "inactive"] |
| pattern | Regex constraint on strings | "pattern": "^[A-Z]{2}\\d{4}$" |
| minimum / maximum | Numeric range bounds | "minimum": 0, "maximum": 100 |
| minLength / maxLength | String length bounds | "minLength": 1, "maxLength": 255 |
| $ref | Reuses another schema by URI | "$ref": "#/$defs/address" |
| additionalProperties | Controls extra keys in objects | "additionalProperties": false |
| anyOf / oneOf / allOf | Combines multiple schemas logically | "anyOf": [{ "type": "string" }, { "type": "null" }] |
| if / then / else | Conditional schema application | "if": { "properties": { "type": { "const": "email" } } } |
JSON Schema ドラフト比較:Draft 7 vs 2019-09 vs 2020-12
JSON Schema はいくつかのドラフトバージョンを経ています。Draft 7(2018年公開)はツールサポートが最も広く普及しています。Draft 2019-09 では $defs(definitions の置き換え)、unevaluatedProperties、$recursiveRef が導入されました。Draft 2020-12(最新の安定版)では $recursiveRef が $dynamicRef に置き換えられ、タプル検証のための prefixItems が導入されました。ドラフトを選ぶ際は、使用する検証ライブラリがそのドラフトをサポートしているか確認してください。Ajv は3つのドラフトすべてをサポートしています。Python の jsonschema ライブラリはバージョン 4.0 以降で 2020-12 まで対応しています。
| 機能 | Draft 7 | Draft 2019-09 | Draft 2020-12 |
|---|---|---|---|
| $schema URI | draft-07/schema# | 2019-09/schema | 2020-12/schema |
| if / then / else | Yes | Yes | Yes |
| $defs (definitions) | definitions | $defs | $defs |
| $ref alongside keys | No (sibling ignored) | Yes | Yes |
| $dynamicRef | No | No ($recursiveRef) | Yes |
| prefixItems | No (use items array) | No (use items array) | Yes |
| unevaluatedProperties | No | Yes | Yes |
| $vocabulary | No | Yes | Yes |
コード例
以下の例は、プログラムから JSON をスキーマに対して検証する方法を示しています。各言語のエコシステムで広く使われているライブラリを使用しています。
import Ajv from 'ajv';
const ajv = new Ajv();
const schema = {
type: 'object',
properties: {
name: { type: 'string', minLength: 1 },
age: { type: 'integer', minimum: 0 },
email: { type: 'string', format: 'email' }
},
required: ['name', 'email'],
additionalProperties: false
};
const data = { name: 'Alice', age: 30, email: 'alice@example.com' };
const validate = ajv.compile(schema);
const valid = validate(data);
console.log(valid); // → true
console.log(validate.errors); // → null
// Invalid data — missing required "email"
validate({ name: 'Bob', age: 25 });
console.log(validate.errors);
// → [{ instancePath: '', keyword: 'required', params: { missingProperty: 'email' } }]from jsonschema import validate, ValidationError
schema = {
"type": "object",
"properties": {
"name": {"type": "string", "minLength": 1},
"age": {"type": "integer", "minimum": 0},
"tags": {
"type": "array",
"items": {"type": "string"},
"uniqueItems": True
}
},
"required": ["name"]
}
# Valid data
validate(instance={"name": "Alice", "age": 30, "tags": ["admin"]}, schema=schema)
# → No exception raised
# Invalid data — wrong type for "age"
try:
validate(instance={"name": "Alice", "age": "thirty"}, schema=schema)
except ValidationError as e:
print(e.message)
# → 'thirty' is not of type 'integer'
print(e.json_path)
# → $.agepackage main
import (
"fmt"
"strings"
"github.com/santhosh-tekuri/jsonschema/v5"
)
func main() {
schemaJSON := `{
"type": "object",
"properties": {
"id": { "type": "integer" },
"status": { "enum": ["active", "inactive"] }
},
"required": ["id", "status"]
}`
compiler := jsonschema.NewCompiler()
compiler.AddResource("schema.json", strings.NewReader(schemaJSON))
schema, _ := compiler.Compile("schema.json")
// Valid data
data := map[string]interface{}{"id": 1, "status": "active"}
err := schema.Validate(data)
fmt.Println(err) // → <nil>
// Invalid — missing "status"
bad := map[string]interface{}{"id": 2}
err = schema.Validate(bad)
fmt.Println(err) // → validation failed: missing properties: 'status'
}# Install via pip pip install check-jsonschema # Validate a file against a schema check-jsonschema --schemafile schema.json data.json # → ok -- validation done # Validate against a remote schema (e.g., GitHub Actions workflow) check-jsonschema --builtin-schema vendor.github-workflows my-workflow.yml # Validate multiple files at once check-jsonschema --schemafile schema.json file1.json file2.json file3.json