alltools.one
JSON
2025-07-09
10 min
alltools.one Team
JSONSchemaValidationAPIData Quality

JSONスキーマバリデーション:決定版ガイド

JSON Schemaは、JSONドキュメントに注釈を付け、バリデーションするための語彙です。データがどのような形状であるべきか、どの型が許容されるか、どのフィールドが必須かを定義する契約を提供します。API、設定ファイル、または構造化データを扱う場合、JSON Schemaは不可欠なツールです。

なぜJSON Schemaを使うのか?

バリデーションなしでは、JSONデータは不確定要素です。年齢フィールドが文字列として来たり、メールが欠落したり、日付が間違ったフォーマットで来るかもしれません。JSON Schemaはこれらの問題を境界で捕捉し、不正なデータがシステムを伝播する前に防ぎます。

主なメリット

  • API契約の施行: リクエストとレスポンスのボディを自動的にバリデーション
  • ドキュメント: スキーマがデータ構造の生きたドキュメントとして機能
  • コード生成: ツールがJSON Schemaから型、フォーム、データベーススキーマを生成可能
  • テスト: テストフィクスチャとモックデータをスキーマに対してバリデーション

基本的なスキーマ構造

すべてのJSON Schemaはいくつかの標準プロパティから始まります:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/user.schema.json",
  "title": "User",
  "description": "A registered user in the system",
  "type": "object",
  "properties": {
    "id": { "type": "integer", "minimum": 1 },
    "name": { "type": "string", "minLength": 1, "maxLength": 100 },
    "email": { "type": "string", "format": "email" },
    "age": { "type": "integer", "minimum": 0, "maximum": 150 }
  },
  "required": ["id", "name", "email"]
}

チームと共有する前にスキーマを読みやすくするには、JSONフォーマッターをご利用ください。

型制約

JSON Schemaは6つのプリミティブ型をサポートします:

説明
stringテキストデータ"hello"
number任意の数値3.14
integer整数のみ42
boolean真偽値true
array順序付きリスト[1, 2, 3]
objectキーバリューペア{"key": "value"}
nullNull値null

文字列制約

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255,
  "pattern": "^[A-Za-z0-9]+$",
  "format": "email"
}

組み込みフォーマットには emailuridatedate-timeipv4ipv6uuidhostname があります。

数値制約

{
  "type": "number",
  "minimum": 0,
  "maximum": 100,
  "exclusiveMinimum": 0,
  "multipleOf": 0.01
}

配列バリデーション

配列はアイテム、長さ、一意性についてバリデーションできます:

{
  "type": "array",
  "items": { "type": "string", "format": "email" },
  "minItems": 1,
  "maxItems": 10,
  "uniqueItems": true
}

タプルバリデーション(位置ごとに特定の型を持つ固定長配列):

{
  "type": "array",
  "prefixItems": [
    { "type": "number" },
    { "type": "string" },
    { "type": "boolean" }
  ],
  "items": false
}

オブジェクトバリデーション

オブジェクトはプロパティバリデーション、必須フィールド、追加プロパティの制御をサポートします:

{
  "type": "object",
  "properties": {
    "name": { "type": "string" },
    "role": { "enum": ["admin", "editor", "viewer"] }
  },
  "required": ["name", "role"],
  "additionalProperties": false
}

additionalPropertiesfalse に設定すると、スキーマで定義されていないプロパティを拒否する厳格モードになります。これはフィールド名のタイポをキャッチしたいAPIに特に有用です。

合成キーワード

JSON Schemaは論理演算子を使用してスキーマを組み合わせることをサポートします:

allOf(AND)

データはすべてのサブスキーマに対して有効でなければなりません:

{
  "allOf": [
    { "$ref": "#/$defs/baseUser" },
    { "properties": { "role": { "const": "admin" } } }
  ]
}

oneOf(XOR)

データは正確に1つのサブスキーマに対して有効でなければなりません:

{
  "oneOf": [
    { "properties": { "type": { "const": "email" }, "email": { "type": "string" } } },
    { "properties": { "type": { "const": "phone" }, "phone": { "type": "string" } } }
  ]
}

anyOf(OR)

データは少なくとも1つのサブスキーマに対して有効でなければなりません。

条件付きバリデーション

if/then/else キーワードで条件付きバリデーションが可能です:

{
  "type": "object",
  "properties": {
    "country": { "type": "string" },
    "postalCode": { "type": "string" }
  },
  "if": {
    "properties": { "country": { "const": "US" } }
  },
  "then": {
    "properties": { "postalCode": { "pattern": "^[0-9]{5}(-[0-9]{4})?$" } }
  },
  "else": {
    "properties": { "postalCode": { "pattern": "^[A-Z0-9 -]+$" } }
  }
}

参照と再利用

$ref を使って再利用可能な定義を参照します:

{
  "$defs": {
    "address": {
      "type": "object",
      "properties": {
        "street": { "type": "string" },
        "city": { "type": "string" },
        "country": { "type": "string" }
      },
      "required": ["street", "city", "country"]
    }
  },
  "type": "object",
  "properties": {
    "billingAddress": { "$ref": "#/$defs/address" },
    "shippingAddress": { "$ref": "#/$defs/address" }
  }
}

実践でのバリデーション

JavaScript(Ajv)

const Ajv = require('ajv');
const ajv = new Ajv();

const validate = ajv.compile(schema);
const valid = validate(data);
if (!valid) console.log(validate.errors);

Python(jsonschema)

from jsonschema import validate, ValidationError

try:
    validate(instance=data, schema=schema)
except ValidationError as e:
    print(f"Validation error: {e.message}")

開発環境を構築せずにクイックバリデーションするには、JSONとスキーマをJSONバリデーターに貼り付けてください。

実践例:APIレスポンススキーマ

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "status": { "enum": ["success", "error"] },
    "data": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "name": { "type": "string" },
          "createdAt": { "type": "string", "format": "date-time" }
        },
        "required": ["id", "name"]
      }
    },
    "pagination": {
      "type": "object",
      "properties": {
        "page": { "type": "integer", "minimum": 1 },
        "perPage": { "type": "integer", "minimum": 1, "maximum": 100 },
        "total": { "type": "integer", "minimum": 0 }
      }
    }
  },
  "required": ["status", "data"]
}

FAQ

JSON Schema draft-07と2020-12の違いは何ですか?

Draft 2020-12ではいくつかの改善が導入されました:prefixItemsitems のタプル形式に取って代わり、$dynamicRef がより柔軟な参照を可能にし、語彙サポートがカスタム拡張を許可します。新しいプロジェクトでは2020-12を使用してください。古いツールとの互換性のためには、draft-07が依然として広くサポートされています。

JSON Schemaは文字列フィールド内のネストされたJSONをバリデーションできますか?

直接的にはできません。JSON Schemaはパースされたjsonの構造をバリデーションします。フィールドにJSON文字列が含まれている場合、先にパースしてから別途バリデーションする必要があります。一部のバリデーターはこれを処理できるカスタムフォーマットバリデーターを提供していますが、標準の一部ではありません。

関連リソース

Published on 2025-07-09
JSON Schema Validation: The Definitive Guide | alltools.one