JSON Schema は JSON データ構造の記述と検証の業界標準です。API リクエストペイロードの強制・設定ファイルの検証・フォームバリデーションロジックの構築など、あらゆる場面でオンライン JSON Schema バリデーターを使えば、ライブラリのインストールもテストハーネスも不要でスキーマとサンプルデータを即座にテストできます。

今すぐ JSON をスキーマでバリデートする →

JSON Schema とは

JSON Schema は JSON ドキュメントに注釈を付けて検証するための宣言的な語彙です。スキーマ自体も JSON(または YAML)ドキュメントで、データの期待される形状・型・制約を記述します。

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": ["id", "email", "role"],
  "properties": {
    "id": { "type": "integer", "minimum": 1 },
    "email": { "type": "string", "format": "email" },
    "role": { "type": "string", "enum": ["admin", "editor", "viewer"] },
    "createdAt": { "type": "string", "format": "date-time" }
  },
  "additionalProperties": false
}

このスキーマは検証する JSON オブジェクトに3つの必須フィールドがあること、id が正の整数、email が有効なメールアドレス、role が3つの許可された値のいずれかであることを保証します。

JSON Schema ドラフトバージョン

仕様は大きく進化しています。バージョンの全体像を理解することで、スキーマが予期しない動作をするときの混乱を防げます:

ドラフトリリース主な追加機能
Draft-042013コア語彙、$refallOf/anyOf/oneOf
Draft-062017constcontainspropertyNamesreadOnly
Draft-072019if/then/elsewriteOnly$comment
2019-092019$defsunevaluatedProperties$anchor
2020-122021Prefix items、$dynamicRef、改善された $ref

常に $schema でドラフトを宣言してください。宣言がないとバリデーターが異なるデフォルトを適用することがあります。現在のプロダクション利用の多くは draft-07 または 2020-12 です。

コアスキーマキーワード

型制約

{ "type": "string" }
{ "type": "integer" }
{ "type": "number" }
{ "type": "boolean" }
{ "type": "null" }
{ "type": "array" }
{ "type": "object" }

// 複数の型を許可:
{ "type": ["string", "null"] }

オブジェクト制約

{
  "type": "object",
  "properties": {
    "name": { "type": "string" },
    "age": { "type": "integer", "minimum": 0 }
  },
  "required": ["name"],
  "additionalProperties": false,
  "minProperties": 1,
  "maxProperties": 10
}

additionalProperties: false は最も効果的な安全制約です。properties に列挙されていないキーをすべて拒否し、タイポや予期しないフィールドを検出します。

文字列制約

{
  "type": "string",
  "minLength": 3,
  "maxLength": 100,
  "pattern": "^[a-z][a-z0-9_]*$",
  "format": "email"
}

一般的な format 値:emailuridatedate-timetimeipv4ipv6uuid。注意:フォーマット検証はデフォルトでオプションです。バリデーターで明示的に有効化する必要があります。

配列制約

{
  "type": "array",
  "items": { "type": "string" },
  "minItems": 1,
  "maxItems": 50,
  "uniqueItems": true
}

draft 2020-12 では、タプル検証のために itemsprefixItems に名称変更されました。均質な配列には items、位置指定のタプルには prefixItems を使います。

数値制約

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

列挙と const

// 許可された値のいずれか:
{ "enum": ["draft", "published", "archived"] }

// ちょうど1つの値(判別共用体に便利):
{ "const": "v2" }

組み合わせキーワード

// すべてのサブスキーマにマッチする必要がある:
{ "allOf": [{ "type": "string" }, { "minLength": 1 }] }

// 少なくとも1つのサブスキーマにマッチする必要がある:
{ "anyOf": [{ "type": "string" }, { "type": "number" }] }

// ちょうど1つのサブスキーマにマッチする必要がある:
{ "oneOf": [
  { "type": "string", "format": "email" },
  { "type": "string", "format": "uri" }
] }

// サブスキーマにマッチしてはならない:
{ "not": { "type": "null" } }

条件付きバリデーション(Draft-07 以降)

{
  "if": { "properties": { "type": { "const": "company" } } },
  "then": { "required": ["companyName", "taxId"] },
  "else": { "required": ["firstName", "lastName"] }
}

これは JSON Schema の最も強力な機能の一つです。別のフィールドの値に基づいて異なる必須フィールドを強制できます。

スキーマ参照と再利用

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$defs": {
    "address": {
      "type": "object",
      "required": ["street", "city", "country"],
      "properties": {
        "street": { "type": "string" },
        "city": { "type": "string" },
        "country": { "type": "string", "minLength": 2, "maxLength": 2 }
      }
    }
  },
  "type": "object",
  "properties": {
    "billingAddress": { "$ref": "#/$defs/address" },
    "shippingAddress": { "$ref": "#/$defs/address" }
  }
}

$defs(古いドラフトでは definitions)はスキーマを DRY に保ちます。$ref はローカル(#/...)とリモート(https://...)参照の両方をサポートします。

コードでの JSON Schema バリデーション

Node.js(AJV)

AJV は最速かつ最も広く使われている JavaScript JSON Schema バリデーターです:

npm install ajv ajv-formats
import Ajv from 'ajv';
import addFormats from 'ajv-formats';

const ajv = new Ajv({ allErrors: true });
addFormats(ajv);

const schema = {
  type: 'object',
  required: ['email', 'age'],
  properties: {
    email: { type: 'string', format: 'email' },
    age: { type: 'integer', minimum: 18 },
  },
  additionalProperties: false,
};

const validate = ajv.compile(schema);
const data = { email: 'user@example.com', age: 25 };

if (validate(data)) {
  console.log('Valid');
} else {
  console.log('Errors:', validate.errors);
}

AJV はスキーマを最適化された JavaScript 関数にコンパイルするため、非常に高速で、ホットリクエストパスにも適しています。

Python(jsonschema)

pip install jsonschema
import jsonschema
from jsonschema import validate, ValidationError

schema = {
    "type": "object",
    "required": ["email", "age"],
    "properties": {
        "email": {"type": "string", "format": "email"},
        "age": {"type": "integer", "minimum": 18},
    },
    "additionalProperties": False,
}

data = {"email": "user@example.com", "age": 25}

try:
    validate(instance=data, schema=schema)
    print("Valid")
except ValidationError as e:
    print(f"Invalid: {e.message}")
    print(f"Path: {list(e.absolute_path)}")

すべてのエラー(最初のものだけでなく)を取得するには jsonschema.Draft202012Validator を使います:

from jsonschema import Draft202012Validator

validator = Draft202012Validator(schema)
errors = list(validator.iter_errors(data))
for error in errors:
    print(f"{'.'.join(str(p) for p in error.path)}: {error.message}")

Go(santhosh-tekuri)

go get github.com/santhosh-tekuri/jsonschema/v6
package main

import (
    "fmt"
    "strings"

    "github.com/santhosh-tekuri/jsonschema/v6"
)

func main() {
    schemaJSON := `{
        "type": "object",
        "required": ["email", "age"],
        "properties": {
            "email": {"type": "string", "format": "email"},
            "age": {"type": "integer", "minimum": 18}
        }
    }`

    compiler := jsonschema.NewCompiler()
    compiler.AddResource("schema.json", strings.NewReader(schemaJSON))
    schema, err := compiler.Compile("schema.json")
    if err != nil {
        panic(err)
    }

    data := map[string]any{"email": "user@example.com", "age": 25}
    if err := schema.Validate(data); err != nil {
        fmt.Println("Invalid:", err)
    } else {
        fmt.Println("Valid")
    }
}

実践的なユースケース

API リクエストバリデーション

ビジネスロジックに到達する前に、ゲートウェイやミドルウェア層で API ペイロードを検証します:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "CreateOrderRequest",
  "type": "object",
  "required": ["customerId", "items", "shippingAddress"],
  "properties": {
    "customerId": { "type": "string", "format": "uuid" },
    "items": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "object",
        "required": ["productId", "quantity"],
        "properties": {
          "productId": { "type": "string" },
          "quantity": { "type": "integer", "minimum": 1 }
        },
        "additionalProperties": false
      }
    },
    "couponCode": { "type": "string", "pattern": "^[A-Z0-9]{6,12}$" }
  }
}

設定ファイルのバリデーション

起動時にアプリケーション設定を検証し、謎めいたランタイムエラーの代わりに明確なエラーメッセージで早期に失敗させます。

JSON Schema vs ランタイムバリデーションライブラリ

アプローチ可搬性言語サポート学習曲線ツール
JSON Schema高(言語中立)主要言語すべて優秀
TypeScript(Zod/Yup)TypeScript のみTypeScript/JS良好
Pydantic(Python)Python のみPython良好
Protobuf/gRPC高(バイナリ)すべて優秀
OpenAPI specすべて優秀

JSON Schema は、ポリグロットスタック全体で共有される単一の正規スキーマが必要な場合に勝ります。一度定義すれば、どの言語でも検証できます。

よくあるミス

additionalProperties: false を設定しない — スキーマが余分なフィールドを受け入れ、クライアントが予期しないデータを渡すことが容易になります。

バリデーターの設定なしに format を使うformat: "email" はアノテーションであり、バリデーターでフォーマット検証を明示的に有効化しない限り制約ではありません。

ドラフトバージョンを混在させる$schema で draft-07 を宣言しながら $defs(2019-09 以降)を使うと未定義の動作が生じます。

required を忘れるrequired がなければすべての properties はデフォルトでオプションです。properties はあるが required 配列がないスキーマは {} に対してバリデーションが通ります。

DB の ID に type: "integer" を使う — 大きな整数 ID(64ビット)は JavaScript の安全な整数の範囲を超える場合があります。"type": "string" を検討するか "maximum": 9007199254740991 を追加してください。

オンライン JSON Schema バリデーター

スキーマをサンプルデータに対してローカルでテストするには、バリデーターのセットアップ・ファイルの読み込み・コードの実行が必要です。ZeroTool の JSON Schema バリデーターはそのすべての手間をなくします:

  • JSON Schema とサンプル JSON を並べて貼り付ける
  • エラーパスをハイライトした即座の検証
  • draft-04・draft-06・draft-07・2019-09・2020-12 に対応
  • 100% ローカル処理 — データはブラウザの外に出ない

JSON Schema バリデーターを試す →