$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" }
}
}
billing と shipping は同じアドレススキーマを共有します。
参照の仕組み
$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仕様で特に価値があります。