スキーマの再利用 — $refと$defsの使い方

JSON Schemaの $ref と $defs(旧 definitions)でスキーマを再利用し、DRYなスキーマ設計を行う方法を解説します。

Advanced

JSON Schema

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "billing": { "$ref": "#/$defs/Address" },
    "shipping": { "$ref": "#/$defs/Address" },
    "items": {
      "type": "array",
      "items": { "$ref": "#/$defs/LineItem" },
      "minItems": 1
    }
  },
  "required": ["billing", "shipping", "items"],
  "$defs": {
    "Address": {
      "type": "object",
      "properties": {
        "street": { "type": "string", "minLength": 1 },
        "city": { "type": "string", "minLength": 1 },
        "state": { "type": "string", "minLength": 1 },
        "postalCode": { "type": "string", "pattern": "^\\d{5}(-\\d{4})?$" },
        "country": { "type": "string", "minLength": 2, "maxLength": 2 }
      },
      "required": ["street", "city", "country"]
    },
    "LineItem": {
      "type": "object",
      "properties": {
        "productId": { "type": "integer", "minimum": 1 },
        "name": { "type": "string", "minLength": 1 },
        "quantity": { "type": "integer", "minimum": 1, "maximum": 999 },
        "unitPrice": { "type": "number", "minimum": 0, "multipleOf": 0.01 }
      },
      "required": ["productId", "name", "quantity", "unitPrice"]
    }
  }
}

Test Data

{
  "billing": {
    "street": "123 Main St",
    "city": "San Francisco",
    "state": "CA",
    "postalCode": "94102",
    "country": "US"
  },
  "shipping": {
    "street": "456 Oak Ave",
    "city": "Los Angeles",
    "state": "CA",
    "postalCode": "90001",
    "country": "US"
  },
  "items": [
    {
      "productId": 1001,
      "name": "Wireless Keyboard",
      "quantity": 2,
      "unitPrice": 49.99
    },
    {
      "productId": 2005,
      "name": "USB-C Cable",
      "quantity": 5,
      "unitPrice": 12.99
    }
  ]
}

詳細な説明

JSON Schemaの $ref キーワードは、他の場所に定義されたスキーマを参照するためのメカニズムです。$defs(旧 definitions)と組み合わせることで、再利用可能なスキーマコンポーネントを定義できます。

基本構文:

{
  "type": "object",
  "properties": {
    "billing_address": { "$ref": "#/$defs/address" },
    "shipping_address": { "$ref": "#/$defs/address" }
  },
  "$defs": {
    "address": {
      "type": "object",
      "required": ["street", "city"],
      "properties": {
        "street": { "type": "string" },
        "city": { "type": "string" },
        "zip": { "type": "string" }
      }
    }
  }
}

$ref の種類:

  • #/$defs/name: 同一ドキュメント内の参照(JSONポインタ)
  • ./other-schema.json: 外部ファイルの参照
  • https://example.com/schema.json: URLによるリモート参照

スキーマが大規模になる場合、$ref を活用してDRY(Don't Repeat Yourself)原則に従ったスキーマ設計を行うことが重要です。

ユースケース

住所、ユーザー情報、エラーレスポンスなどの共通構造を複数のスキーマで再利用する際に使用します。

試してみる — JSON Schema Validator

フルツールを開く