$ref と $defs — 再利用可能なスキーマ定義

JSON Schemaの $ref と $defs を使用して再利用可能な定義を作成します。共有サブスキーマを抽出してスキーマ全体で参照し、重複を排除します。

Advanced Patterns

詳細な説明

$ref$defs による再利用可能なスキーマ

スキーマが大きくなると、同じ構造が複数の場所に現れることがよくあります。$ref キーワードを使えば、重複せずに共有定義を参照できます。

基本的な $defs$ref

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

billingshipping は同じアドレススキーマを共有します。

参照の仕組み

  • $ref はJSONポインタを使用してターゲットスキーマを特定します。#/$defs/address は「ルート(#)から始めて $defs に移動し、次に address に移動する」ことを意味します。
  • $defs はDraft 2020-12での再利用可能な定義の標準的な配置場所です。古いドラフトでは definitions$ プレフィックスなし)を使用していました。

外部参照

参照は外部ファイルを指すこともできます:

{ "$ref": "https://example.com/schemas/address.json" }

再帰的スキーマ

$ref は自分自身を参照する再帰的な構造を可能にします:

{
  "$defs": {
    "node": {
      "type": "object",
      "properties": {
        "value": { "type": "string" },
        "children": {
          "type": "array",
          "items": { "$ref": "#/$defs/node" }
        }
      }
    }
  },
  "$ref": "#/$defs/node"
}

これは各ノードが同じ形状の子ノードを持つことができるツリー構造をモデル化します。

ユースケース

アドレス、ユーザーオブジェクト、エラーレスポンスなどの繰り返し構造を含むスキーマで $ref と $defs を使用します。これは、数十のエンドポイントが共通モデルを共有する大規模なOpenAPI仕様で特に価値があります。

試してみる — JSON Schema Generator

フルツールを開く