| Internet-Draft | JSON Schema | 2022年6月 |
| Wrightほか | 2022年12月18日に失効 | [ページ] |
JSON Schemaは、JSONデータの構造を記述するためのJSONベースの形式である メディアタイプ"application/schema+json"を定義します。 JSON Schemaは、JSON文書がどのような外観でなければならないか、 そこから情報を抽出する方法、 およびそれとどのようにやり取りするかを表明します。 "application/schema-instance+json"メディアタイプは、 "application/json"文書に対して提供できるものを超える、 "application/schema+json"との機能豊富な追加の統合を提供します。¶
この草案の課題リストは、 https://github.com/json-schema-org/json-schema-spec/issuesにあります。¶
追加情報については、https://json-schema.org/を参照してください。¶
フィードバックを提供するには、この課題トラッカー、ホームページに記載されている 連絡方法、または文書の編集者へのメールを使用してください。¶
このInternet-Draftは、BCP 78およびBCP 79の規定に 完全に準拠して提出されています。¶
Internet-Draftは、Internet Engineering Task Force (IETF)の作業文書です。他のグループも作業 文書をInternet-Draftとして配布する場合があることに注意してください。現在のInternet-Draftの一覧は、 https://datatracker.ietf.org/drafts/current/にあります。¶
Internet-Draftは最長6か月間有効な草案文書であり、 いつでも他の文書によって更新、置換、または廃止される 可能性があります。Internet-Draftを参照資料として使用したり、 「進行中の作業」として以外に引用したりすることは不適切です。¶
このInternet-Draftは2022年12月18日に失効します。¶
Copyright (c) 2022 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
JSON Schemaは、JSONデータの構造を定義するためのJSONメディアタイプです。JSON Schemaは、 JSONデータの検証、文書化、ハイパーリンクナビゲーション、およびインタラクション制御を 定義することを意図しています。¶
この仕様は、JSON Schemaの中核となる用語と仕組みを定義します。これには、 参照によって別のJSON Schemaを指すこと、 JSON Schema参照を逆参照すること、 使用されるダイアレクトを指定すること、 ダイアレクトの語彙要件を指定すること、 および期待される出力を定義することが含まれます。¶
他の仕様は、検証、リンク、注釈、ナビゲーション、およびインタラクションに関する アサーションを行う語彙を定義します。¶
この文書におけるキーワード"MUST"、"MUST NOT"、"REQUIRED"、"SHALL"、"SHALL NOT"、"SHOULD"、 "SHOULD NOT"、"RECOMMENDED"、"MAY"、および"OPTIONAL"は、 RFC 2119 [RFC2119]で説明されているように解釈されるものとします。¶
この文書における用語"JSON"、"JSON text"、"JSON value"、"member"、"element"、"object"、"array"、 "number"、"string"、"boolean"、"true"、"false"、および"null"は、 RFC 8259 [RFC8259]で定義されているように解釈されるものとします。¶
この文書は、JSONデータを記述するためのJSON Schemaを識別する新しいメディアタイプ"application/schema+json"を提案します。 また、追加の統合機能を提供するため、さらに任意のメディアタイプ "application/schema-instance+json"も提案します。 JSON Schema自体はJSON文書です。 この仕様および関連仕様は、作成者がJSONデータを複数の方法で記述できるようにする キーワードを定義します。¶
JSON Schemaは、JSONインスタンスに制約を表明したり、それらの インスタンスに追加情報を注釈したりするためにキーワードを使用します。追加のキーワードは、 より複雑なJSONデータ構造に対して、または何らかの条件に基づいて、 アサーションと注釈を適用するために使用されます。¶
再利用を容易にするため、キーワードは語彙として編成できます。語彙は、 キーワードの一覧と、それらの構文および意味論から構成されます。 ダイアレクトは、メタスキーマ内で識別される語彙の集合と それらの必須サポートとして定義されます。¶
JSON Schemaは、追加の語彙を定義することによって、 または、より非形式的には語彙の外側で追加のキーワードを定義することによって拡張できます。 認識されない個々のキーワードは単にその値が注釈として収集されますが、 認識されない語彙に関する振る舞いは、使用中の語彙を宣言する際に 制御できます。¶
この文書は、すべての実装がサポートしなければならず、 無効にできないコア語彙を定義します。そのキーワードはそれぞれ、 必須の性質を強調するために"$"文字で始まります。この語彙は "application/schema+json"メディアタイプの機能に不可欠であり、 他の語彙の読み込みをブートストラップするために使用されます。¶
さらに、この文書は、サブスキーマを条件付きで適用し、 オブジェクトと配列の内容にサブスキーマを適用するためのキーワードからなる RECOMMENDED語彙を定義します。この語彙、またはこれに非常によく似た語彙は、 重要なJSONインスタンスのためのスキーマを書くために必要です。 そのスキーマがアサーション検証、注釈、 またはその両方を目的としているかどうかは問いません。必須の コア語彙の一部ではありませんが、最大限の相互運用性のために この追加語彙はこの文書に含まれており、その使用が強く推奨されます。¶
構造検証やハイパーメディア注釈などの目的のためのさらなる語彙は、 他の文書で定義されます。これらの他の文書はそれぞれ、 その文書の目的のためにスキーマを書くために必要な標準的な語彙集合を 収集するダイアレクトを定義します。¶
JSON文書とは、application/jsonメディアタイプによって記述される情報リソース (オクテット列)です。¶
JSON Schemaでは、それが定義するデータモデルのため、"JSON document"、 "JSON text"、および"JSON value"という用語は相互に置き換え可能です。¶
JSON SchemaはJSON文書の上でのみ定義されます。ただし、JSON Schemaデータ モデルに解析できる、またはそのモデルに従って処理できる任意の文書またはメモリ 構造は、JSON Schemaに照らして解釈できます。これには、 CBOR [RFC7049]のようなメディアタイプも含まれます。¶
スキーマが適用されるJSON文書は、「インスタンス」と呼ばれます。¶
JSON Schemaは、"application/json"または互換性のある文書の上で定義されます。 これには"+json"構造化構文接尾辞を持つメディアタイプが含まれます。¶
これらの中で、この仕様は、URI内のフラグメントの扱いを定義する "application/schema-instance+json"メディアタイプを定義します。¶
JSON Schemaは、データモデルに従って文書を解釈します。このデータモデルに 従って解釈されるJSON値は「インスタンス」と呼ばれます。¶
インスタンスは6つのプリミティブ型のいずれかを持ち、その型に応じた 取り得る値の範囲を持ちます。¶
したがって、データモデル内で等しい数値の異なる字句表現を含む、 空白や整形に関する問題は、JSON Schemaの範囲外です。JSON Schemaの 語彙(セクション8.1)が、 そのような字句表現の違いを扱いたい場合は、元のJSON表現のUnicode 文字が利用可能であることに依存するのではなく、データモデル内の整形済み文字列を 正確に解釈するキーワードを定義するべきです。 ¶
オブジェクトは同じキーを持つ2つのプロパティを持てないため、 単一のオブジェクト内で同じキーを持つ2つのプロパティを 定義しようとするJSON文書の振る舞いは未定義です。¶
JSON Schema語彙は、独自の拡張型システムを自由に定義できることに注意してください。 これは、ここで定義されるコアデータモデル型と混同すべきではありません。 例として、"integer"は語彙がキーワードの値として定義するのに妥当な型ですが、 データモデルは整数と他の数値を区別しません。¶
2つのJSONインスタンスは、同じ型であり、かつデータモデルに従って同じ値を持つ場合、 かつその場合に限り、等しいと言われます。具体的には、これは次を意味します。¶
この定義には、配列は同じ長さでなければならないこと、 オブジェクトは同じ数のメンバーを持たなければならないこと、 オブジェクト内のプロパティには順序がないこと、 同じキーを持つ複数のプロパティを定義する方法はないこと、 そして単なる整形の違い(インデント、カンマの位置、末尾のゼロ)は 意味を持たないことが含意されています。¶
JSON Schemaデータモデルの上位集合とともにJSON Schemaを使用することは可能であり、 その場合、インスタンスは6つのJSONデータ型のいずれにも属さない可能性があります。¶
この場合でも注釈は適用されますが、ほとんどの検証キーワードは有用ではありません。 それらは常に成功するか常に失敗するためです。¶
カスタム語彙は、コアデータモデルの上位集合のサポートを定義できます。 スキーマ自体はこの上位集合でのみ表現可能な場合があります。 例えば、"const"キーワードを利用する場合です。¶
JSON Schema文書、または単にスキーマとは、インスタンスを記述するために使用される JSON文書です。 スキーマ自体はインスタンスとして解釈できますが、常に "application/schema-instance+json"ではなく "application/schema+json"メディアタイプを与えるべきです。"application/schema+json"メディア タイプは、"application/schema-instance+json"によって提供される フラグメント識別子の構文と意味論の上位集合を提供するように定義されています。¶
JSON Schemaはオブジェクトまたはブール値でなければなりません。¶
インスタンスに適用されるオブジェクトプロパティは、キーワード、 またはスキーマキーワードと呼ばれます。大まかに言えば、キーワードは 次の5つのカテゴリのいずれかに分類されます。¶
キーワードは複数のカテゴリに属する場合がありますが、アプリケーターは そのサブスキーマの結果に基づくアサーション結果のみを生成すべきです。 それらはサブスキーマから独立した追加の制約を定義すべきではありません。¶
同じスキーマオブジェクト内のプロパティであるキーワードは、隣接 キーワードと呼ばれます。¶
拡張キーワード、すなわちこの文書およびその関連文書の外で定義されるキーワードは、 他の振る舞いも自由に定義できます。¶
JSON Schemaは、スキーマキーワードではないプロパティを含んでもかまいません。 不明なキーワードは注釈として扱うべきであり、そのキーワードの値が 注釈の値となります。¶
空のスキーマとは、プロパティを持たない、または不明なプロパティのみを持つ JSON Schemaです。¶
ブールスキーマ値"true"および"false"は、インスタンス値にかかわらず、 常にそれ自身をアサーション結果として生成する自明なスキーマです。 それらは注釈結果を生成しません。¶
これらのブールスキーマは、スキーマ作成者の意図を明確にし、 スキーマ処理の最適化を容易にするために存在します。それらは次のスキーマオブジェクトと 同一に振る舞います(ここで"not"は、この文書で定義される サブスキーマ適用語彙の一部です)。¶
空のスキーマオブジェクトは曖昧ではありませんが、"false"スキーマには 多くの等価な表現があり得ます。ブール値を使用することで、 人間の読者と実装の双方にとって意図が明確になります。¶
スキーマ語彙、または単に語彙とは、キーワード、その構文、 およびその意味論の集合です。語彙は一般に特定の目的を中心に 編成されます。検証、ハイパーメディア、ユーザーインターフェース生成など、 JSON Schemaの異なる用途には、異なる語彙集合が関わります。¶
語彙はJSON Schemaにおける再利用の主要な単位です。スキーマ作成者は、 スキーマを処理するために必要または任意の語彙を示すことができるためです。 語彙はメタスキーマ内のURIによって識別されるため、汎用実装は 以前は未知だった語彙をサポートするための拡張を読み込むことができます。 キーワードはどの語彙の外でもサポートできますが、個々の キーワードの使用を示す類似の仕組みはありません。¶
スキーマ語彙は、対象読者および相互運用性の期待に応じて、 非形式的な説明から標準提案まで、さまざまなものによって定義できます。 特に、非公開組織内での語彙の使用を容易にするために、 語彙仕様はその使用範囲の外に公開される必要はありません。¶
スキーマそのものを記述するスキーマは、メタスキーマと呼ばれます。 メタスキーマは、JSON Schemaを検証し、それらが使用している語彙を 指定するために使用されます。¶
通常、メタスキーマは語彙集合を指定し、それらの語彙の構文に適合する スキーマを検証します。ただし、メタスキーマと語彙は分離されています。 これは、メタスキーマが語彙仕様で求められるよりも厳密に、またはより緩やかに スキーマ適合性を検証できるようにするためです。メタスキーマは、 形式的な語彙の一部ではない追加キーワードを記述し検証することもできます。¶
JSON Schemaリソースとは、 正準的に [RFC6596] 絶対URI [RFC3986]によって識別されるスキーマです。スキーマリソースは、 フラグメントを持つURIを含むURIによって識別されてもかまいません。 ただし、その結果となる二次リソース( RFC 3986のセクション3.5 [RFC3986]で定義される)が 一次リソースと同一である場合に限ります。これは空のフラグメント、 またはあるスキーマリソースが別のリソースに埋め込まれている場合に 発生し得ます。そのようなフラグメント付きURIはすべて非正準と見なされます。¶
ルートスキーマとは、対象となるJSON文書全体を構成するスキーマです。 ルートスキーマは常にスキーマリソースであり、そのURIはセクション 9.1.1で説明されるように決定されます。 別の形式内にスキーマを埋め込む文書は、この意味での ルートスキーマリソースを持たないことに注意してください。そのような使用方法が JSON Schema文書およびリソースの概念とどのように適合するかは、 将来の草案で明確化されます。 ¶
一部のキーワードはスキーマ自体を取り、JSON Schemaを入れ子にできます。¶
{
"title": "root",
"items": {
"title": "array item"
}
}
¶
この例の文書では、"array item"というタイトルのスキーマがサブスキーマであり、 "root"というタイトルのスキーマがルートスキーマです。¶
ルートスキーマと同様に、サブスキーマはオブジェクトまたはブール値のいずれかです。¶
セクション 8.2.1で説明されているように、JSON Schema文書は 複数のJSON Schemaリソースを含むことができます。修飾なしに使用される場合、 用語「ルートスキーマ」は文書のルートスキーマを指します。場合によっては、 リソースルートスキーマが議論されます。リソースのルートスキーマとは、 その最上位のスキーマオブジェクトであり、そのリソースが独立したJSON Schema文書として 抽出された場合には文書ルートスキーマにもなるものです。¶
複数のスキーマリソースが埋め込まれているか、参照によってリンクされているかにかかわらず、 それらは同じ利用可能な振る舞いを用いて、同じ方法で処理されます。¶
RFC 6839 [RFC6839]のセクション3.1に従い、 任意の+jsonメディアタイプに対して指定されるフラグメント識別子の 構文と意味論は、"application/json"に対して指定されるものと 同じであるべきです。 (この文書の公開時点では、"application/json"に対して定義された フラグメント識別構文はありません。)¶
さらに、"application/schema+json"メディアタイプは2つの フラグメント識別子構造、すなわちプレーン名とJSON Pointerをサポートします。 "application/schema-instance+json"メディアタイプは1つの フラグメント識別子構造、すなわちJSON Pointerをサポートします。¶
URIフラグメント識別子としてのJSON Pointerの使用は、 RFC 6901 [RFC6901]で説明されています。 2つのフラグメント識別子構文をサポートする"application/schema+json"では、 空文字列を含め、JSON Pointer構文に一致するフラグメント識別子は、 JSON Pointerフラグメント識別子として解釈しなければなりません。¶
W3Cの フラグメント 識別子のベストプラクティス [W3C.WD-fragid-best-practices-20121025]に従い、 "application/schema+json"におけるプレーン名フラグメント識別子は、 ローカルに名前付けされたスキーマを参照するために予約されています。JSON Pointer構文に 一致しないすべてのフラグメント識別子は、 プレーン名フラグメント識別子として解釈しなければなりません。¶
"application/schema+json"文書内でプレーン名フラグメント識別子を 定義および参照することは、 "$anchor"キーワード(セクション8.2.2)のセクションで規定されています。¶
インスタンスは、JSON [RFC8259]で定義される任意の有効なJSON値であり得ます。 JSON Schemaは型に制限を課しません。JSON Schemaは、例えばnullを含む任意のJSON 値を記述できます。¶
JSON Schemaはプログラミング言語に依存せず、データモデルで記述される 値の全範囲をサポートします。 ただし、一部の言語やJSONパーサーは、JSONで記述可能な値の全範囲を メモリ内で表現できない場合があることに注意してください。¶
一部のプログラミング言語やパーサーは、浮動小数点数と整数に対して 異なる内部表現を使用します。¶
一貫性のため、整数のJSON数値は小数部を付けてエンコードするべきではありません。¶
キーワードは、制約を表現するため、またはインスタンス値を正規表現に 制約するために正規表現を使用してもかまいません。 これらの正規表現は、ECMA-262、セクション21.2.1 [ecma262]で説明される正規表現 ダイアレクトに従って有効であるべきです。¶
正規表現は、Unicodeサポートを提供するために"u"フラグ(または同等のもの)を付けて 構築するべきであり、またはECMA-262で定義されるUnicodeサポートを 提供する方法で処理するべきです。¶
さらに、正規表現構文のサポートには大きな差があるため、 スキーマ作成者は、次の正規表現トークンに限定するべきです。¶
最後に、実装は、正規表現が先頭または末尾のいずれにも アンカーされているものとして扱ってはなりません。これは、例えば、 パターン"es"が"expression"に一致することを意味します。¶
追加のスキーマキーワードおよびスキーマ語彙は、任意の主体によって 定義されてもかまいません。明示的な合意がない限り、スキーマ作成者は、 そのようなサポートを明示的に文書化していない実装によって、 これらの追加キーワードおよび語彙がサポートされることを 期待してはなりません。 実装は、サポートしていないキーワードを注釈として扱うべきであり、 そのキーワードの値が注釈の値になります。¶
実装は、直接サポートしていない語彙のためにハンドラーを 登録または読み込む機能を提供してもかまいません。そのようなハンドラーを 登録および実装する正確な仕組みは実装依存です。¶
JSON Schemaキーワードはいくつかの一般的な振る舞いカテゴリに分類されます。 アサーションは、インスタンスが制約を満たすことを検証し、 ブール結果を生成します。注釈は、アプリケーションが 適切と考える任意の方法で使用できる情報を付加します。 アプリケーターは、インスタンスの一部にサブスキーマを適用し、 その結果を結合します。¶
拡張キーワードは、特に注釈が非常に柔軟であることを念頭に置き、 これらのカテゴリ内に留まるべきです。複雑な振る舞いは通常、 スキーマキーワードとして直接実装するよりも、注釈データに基づいて アプリケーションに委任する方が適しています。ただし、拡張 キーワードは特殊な目的のために他の振る舞いを定義してもかまいません。¶
スキーマに対してインスタンスを評価することは、スキーマ内のすべての キーワードを、インスタンス内の適切な位置に対して処理することを伴います。 通常、アプリケーターキーワードは、アプリケーター(したがってサブスキーマ)を持たない スキーマオブジェクトに到達するまで処理されます。インスタンス内の適切な 位置が、スキーマオブジェクト内のアサーションおよび注釈キーワードに対して評価され、 それらの結果は、アプリケーターの規則に従って親スキーマに集約されます。¶
親スキーマオブジェクトの評価は、そのすべてのサブスキーマが評価された時点で 完了できますが、状況によってはアサーション結果により評価が 短絡される場合があります。注釈が収集されている場合、 注釈収集のために、アサーション結果をそれ以上変更できないサブスキーマを含め、 すべてのサブスキーマを調べる必要があるため、一部のアサーション結果の 短絡は不可能です。¶
ほとんどのJSON Schemaキーワードは単独で評価できるか、 多くても同じスキーマオブジェクト内の隣接キーワードの値や結果を 考慮するだけで済みますが、いくつかはより 複雑な振る舞いを持ちます。¶
キーワードの字句スコープは、オブジェクトおよび配列からなる入れ子のJSON データ構造によって決定されます。そのような最大のスコープは スキーマ文書全体です。最小のスコープは、サブスキーマを持たない単一の スキーマオブジェクトです。¶
キーワードは、URI-referenceのような部分値を持つように定義されてもよく、 それは別のURI-referenceや完全なURIのような別の値に対して解決されなければ ならず、その値はJSON文書の字句構造を通じて見つかります。 "$id"、"$ref"、"$dynamicRef"のコアキーワード、および "base" JSON Hyper-Schemaキーワードは、この種の振る舞いの例です。¶
"$schema"などの一部のキーワードは、スキーマリソース全体の字句 スコープに適用されるため、スキーマリソースのルートスキーマにのみ 現れなければならないことに注意してください。¶
他のキーワードは、通常インスタンス文書とともにスキーマを評価している 間に存在する動的スコープを考慮する場合があります。 最も外側の動的スコープは、たとえそれがスキーマリソースルートでなくても、 処理が開始されるスキーマオブジェクトです。 このルートスキーマから任意の特定キーワードまでのパス(解決された可能性のある "$ref"および"$dynamicRef"キーワードを含む)は、そのキーワードの 「検証パス」と見なされます。¶
参照キーワードに遭遇するまでは、字句スコープと動的スコープは一致します。 参照キーワードをたどることにより処理はある字句スコープから別の字句スコープへ移動しますが、 動的スコープの観点では、参照をたどることは値として存在するサブスキーマへ 降りることと何ら変わりません。その参照の先にあるキーワードが 動的スコープを通じて情報を解決する場合、ローカルの字句的に囲む親を調べるのではなく、 参照元側をその動的親と見なします。¶
動的スコープの概念は主に"$dynamicRef"および "$dynamicAnchor"で使用され、追加キーワードを定義する際には 高度な機能と見なして慎重に使用すべきです。これは、同じ字句スコープを 異なる動的スコープで繰り返し訪れる可能性があるため、エラーや収集された注釈の 報告時にも現れます。そのような場合、エラーまたは注釈を生成した 動的パスをユーザーに知らせることが重要です。¶
キーワードの振る舞いは、サブスキーマ(セクション 4.3.5)および/または隣接キーワード (同じスキーマオブジェクト内のキーワード)とそのサブスキーマの 注釈結果の観点で定義されてもかまいません。 そのようなキーワードは循環依存を引き起こしてはなりません。 キーワードは、同じ スキーマオブジェクト(セクション4.3)内の別のキーワードの有無に基づいて、 その振る舞いを変更してもかまいません。¶
欠落しているキーワードは、偽のアサーション結果を生成してはならず、 注釈結果を生成してはならず、また自身の振る舞い定義の一部として 他のスキーマを評価させてはなりません。 ただし、欠落しているキーワードは注釈に寄与しないため、 注釈結果がないことが、他のキーワードの振る舞いを間接的に 変える場合があります。¶
場合によっては、キーワードが欠落しているときのアサーションの振る舞いが、 特定の値によって生成される振る舞いと同一であり、キーワード定義は 既知の場合にはそのような値を記載すべきです。ただし、既定の振る舞いを 生成する値が、存在する場合には注釈結果を生成するとしても、 既定の振る舞いは注釈を結果として生じてはなりません。¶
注釈収集は計算量とメモリの両方に大きなコストを加える可能性があるため、 実装はこの機能を選択しないことができます。 収集された注釈の観点で規定されるキーワードは、適切な場合には 妥当な代替手法を説明すべきです。 この手法は、この文書の "items"および "additionalProperties"キーワードで示されています。¶
なお、あるキーワードについてそのような代替手法が不可能な場合、 注釈収集をサポートしない実装は、それらのキーワードまたはそれらを含む語彙を サポートできません。¶
識別子はスキーマのURIを定義するか、 参照(セクション8.2.3)においてそのようなURIが どのように解決されるかに影響を与えるか、またはその両方を行います。 この文書で定義されるCore語彙は、いくつかの 識別キーワードを定義しており、特に"$id"が重要です。¶
正準スキーマURIはインスタンスの処理中に変わってはなりませんが、 URI-referenceの解決に影響するキーワードは、その振る舞いが 実行時にのみ完全に決定される場合があります。¶
カスタム識別子キーワードは可能ですが、語彙設計者は コアキーワードの機能を妨げないよう注意すべきです。例えば、 この仕様の"$dynamicAnchor"キーワードは、そのURI解決効果を 一致する"$dynamicRef"キーワードに限定し、"$ref"の振る舞いを 妨げません。¶
アプリケーターにより、単一のスキーマオブジェクトでは実現できない より複雑なスキーマを構築できます。インスタンスを スキーマ文書(セクション4.3)に対して評価することは、 完全なインスタンス文書に ルートスキーマ(セクション 4.3.5)を適用することから始まります。 そこから、アプリケーターとして知られるキーワードが、どの追加スキーマを 適用するかを決定するために使用されます。そのようなスキーマは、現在位置にその場で 適用される場合も、子の位置に適用される場合もあります。¶
適用されるスキーマは、キーワード値の全部または一部を構成する サブスキーマとして存在する場合があります。あるいは、アプリケーターは 同じスキーマ文書内または別の文書内のスキーマを参照する場合があります。 そのような参照されるスキーマを識別する仕組みは、キーワードによって定義されます。¶
アプリケーターキーワードはまた、サブスキーマまたは参照スキーマの ブールアサーション(セクション7.6) 結果をどのように変更および/または結合して、アプリケーターのブール結果を 生成するかを定義します。アプリケーターはサブスキーマのアサーション結果に 任意のブール論理演算を適用できますが、独自の新しい アサーション条件を導入してはなりません。¶
注釈(セクション7.7)結果は、 インスタンス位置およびスキーマキーワードの位置とともに 保持されるため、アプリケーションは複数の値をどのように 解釈するかを決定できます。¶
セクション7.5で述べたように、アプリケーターキーワードは 適用されるスキーマを、アプリケーター値内のサブスキーマとして含めるのではなく 参照する場合があります。そのような状況では、 適用されるスキーマは参照されるスキーマと呼ばれ、 アプリケーターキーワードを含むスキーマは参照するスキーマです。¶
ルートスキーマおよびサブスキーマは、スキーマ文書内での スキーマの位置に基づく静的な概念ですが、参照されるスキーマと 参照するスキーマは動的です。インスタンスをスキーマに対して評価する間に、 異なるスキーマの組がさまざまな参照される/参照する関係になる場合があります。¶
"$ref"(セクション 8.2.3.1)のような一部の参照によるアプリケーターでは、 参照されるスキーマはスキーマ文書の字句スコープの静的解析によって 決定できます。"$dynamicRef"("$dynamicAnchor"とともに)のような他のものは、 動的スコープを利用する場合があり、そのためインスタンスとともにスキーマを評価する 過程でのみ解決可能です。¶
JSON Schemaは、JSON文書に対して制約を表明するために使用でき、 その文書はアサーションに合格するか失敗します。この手法は、 制約への適合性を検証するため、または制約を満たすために必要なことを 文書化するために使用できます。¶
JSON Schema実装は、スキーマアサーションに対してインスタンスを評価する際に、 単一のブール結果を生成します。¶
インスタンスは、スキーマ内に存在するアサーションにのみ失敗できます。¶
ほとんどのアサーションは、特定のプリミティブ型内の値のみを 制約します。インスタンスの型がキーワードの対象とする型ではない場合、 インスタンスはそのアサーションに適合すると見なされます。¶
例えば、関連する 検証語彙 [json-schema-validation]の "maxLength"キーワードは、 特定の文字列(長すぎるもの)のみを有効でないように制限します。 インスタンスが数値、ブール値、null、配列、またはオブジェクトである場合、 そのインスタンスはこのアサーションに対して有効です。¶
この振る舞いにより、複数のプリミティブ型を取り得るインスタンスに対して キーワードをより容易に使用できます。関連する検証 語彙には、インスタンスを1つ以上のプリミティブ型に独立して 制限できる"type"キーワードも含まれます。これにより、 例えば、特定の長さの文字列またはnull値のいずれかを返す可能性のある関数のような ユースケースを簡潔に表現できます。¶
{
"type": ["string", "null"],
"maxLength": 255
}
¶
"maxLength"もインスタンス型を文字列に制限する場合、 この例は実際にはnull値を許可しないため、これを表現することは かなり煩雑になります。 各キーワードは、明示的に別途指定されない限り個別に評価されるため、 "maxLength"がインスタンスを文字列に制限する場合、 "type"に"null"を含めても有用な効果はありません。¶
JSON Schemaは、インスタンスが注釈を含むスキーマオブジェクトおよび そのすべての親スキーマオブジェクトに対して検証に成功する場合に、 そのインスタンスに情報を注釈できます。その情報は単純な値である場合も、 インスタンスの内容に基づいて計算される場合もあります。¶
注釈はインスタンス内の特定の位置に付加されます。 多くのサブスキーマが任意の1つの 位置に適用される可能性があるため、アプリケーションは、 異なるスキーマオブジェクト内の同じスキーマキーワードによって 同じインスタンス位置に付加された異なる注釈値をどのように扱うかを 決定する必要がある場合があります。¶
アサーション結果とは異なり、注釈データはさまざまな形式を取り得ます。 これは、アプリケーションが適切と考える方法で使用できるように提供されます。JSON Schema 実装は、アプリケーションに代わって収集された情報を使用することを 期待されていません。¶
別途指定がない限り、注釈キーワードの値はそのキーワードの値です。 ただし、他の振る舞いも可能です。 例えば、JSON Hyper-Schema [json-hyper-schema]の "links"キーワードは、部分的にインスタンスデータに基づいて値を生成する 複雑な注釈です。¶
アサーションでは「短絡」評価が可能ですが、注釈を収集するには、 全体のアサーション結果を変更できない場合でも、インスタンス位置に適用される すべてのスキーマを調べる必要があります。 唯一の例外は、検証に失敗したスキーマオブジェクトのサブスキーマは スキップしてもよいということです。失敗したスキーマの注釈は保持されないためです。¶
注釈は、注釈収集の振る舞いを明示的に定義するキーワードによって収集されます。 ブールスキーマはキーワードを使用しないため、注釈を 生成できないことに注意してください。¶
収集された注釈は、次の情報を含まなければなりません。¶
アプリケーションは、値を提供したスキーマ位置に基づいて、 複数の注釈値のうちどれを使用するかを決定してもかまいません。 これは柔軟な使用を可能にすることを意図しています。スキーマ位置を収集することで そのような使用が容易になります。¶
例えば、 Validation仕様 [json-schema-validation]の注釈とアサーションを使用する 次のスキーマを考えてください。¶
明確さのため、一部の行が折り返されていることに注意してください。¶
{
"title": "Feature list",
"type": "array",
"prefixItems": [
{
"title": "Feature A",
"properties": {
"enabled": {
"$ref": "#/$defs/enabledToggle",
"default": true
}
}
},
{
"title": "Feature B",
"properties": {
"enabled": {
"description": "If set to null, Feature B
inherits the enabled
value from Feature A",
"$ref": "#/$defs/enabledToggle"
}
}
}
],
"$defs": {
"enabledToggle": {
"title": "Enabled",
"description": "Whether the feature is enabled (true),
disabled (false), or under
automatic control (null)",
"type": ["boolean", "null"],
"default": null
}
}
}
¶
この例では、Feature AとFeature Bの両方が、再利用可能な "enabledToggle"スキーマを使用しています。そのスキーマは"title"、"description"、 および"default"注釈を使用します。そのため、アプリケーションは Feature Aに対する追加の"default"値と、Feature Bに対する追加の "description"値をどのように扱うかを決定しなければなりません。¶
アプリケーションプログラマーとスキーマ作成者は、その使用方法について合意する必要があります。 この例では、最も具体的な"default"値が使用され、追加のより汎用的な "default"値は黙って無視されることに合意していると仮定します。また、 すべての"description"テキストを、最も汎用的なものから始めて 最も具体的なものへと使用することにも合意していると仮定します。これには、 スキーマ作成者が、このように組み合わせたときに機能する説明を書くことが必要です。¶
アプリケーションは、どの値がどれであるかを判断するためにスキーマ位置パスを使用できます。 機能の直近の"enabled"プロパティスキーマ内の値はより具体的であり、 "$ref"で参照される再利用可能なスキーマの下の値はより汎用的です。 スキーマ位置パスは、各値が"$ref"を越えて見つかったかどうかを示します。¶
したがってFeature Aは既定値trueを使用し、Feature Bは汎用の既定値nullを使用します。 Feature Aは"enabledToggle"スキーマからの汎用説明のみを持ち、 Feature Bはその説明を使用し、さらにnull値をどのように解釈するかを説明する ローカルに定義された説明も追加します。¶
別のアプリケーションが採用し得る、他の妥当な手法も存在することに注意してください。 例えば、アプリケーションは、スキーマ位置にかかわらず、 "default"に2つの異なる値が存在することをエラーと見なす場合があります。¶
偽のアサーション結果を生成するスキーマオブジェクトは、 自身のキーワードからであれサブスキーマ内のキーワードからであれ、 いかなる注釈結果も生成してはなりません。¶
全体のスキーマ結果には、他のスキーマ位置から収集された注釈が まだ含まれ得ることに注意してください。次のスキーマがあるとします。¶
{
"oneOf": [
{
"title": "Integer Value",
"type": "integer"
},
{
"title": "String Value",
"type": "string"
}
]
}
¶
インスタンス"This is a string"に対しては、
そのスキーマオブジェクト内の型アサーションが失敗するため、title注釈
"Integer Value"は破棄されます。インスタンスが文字列型アサーションに合格するため、
title注釈"String Value"は保持されます。¶
アプリケーターキーワードは、自身の注釈結果を定義する可能性に加えて、 そのサブスキーマまたは参照スキーマで収集された注釈を集約します。¶
4番目のカテゴリのキーワードは、単に再利用可能なコンポーネントや、 スキーマ作成者にとって関心のあるが再利用には適さないデータを保持する位置を 予約します。これらのキーワードは検証結果または注釈結果に影響しません。 コア語彙におけるその目的は、特定の目的のために位置が 利用可能であり、拡張キーワードによって再定義されないことを確保することです。¶
これらのキーワードは結果に直接影響しませんが、セクション 9.4.2で説明されているように、 再利用可能なスキーマのために位置を予約する認識されない 拡張キーワードは、特定の状況では参照と望ましくない相互作用を起こす場合があります。¶
この文書または関連文書の一部として定義される語彙のいずれも、 インスタンスデータを対象にしたり読み込んだりできるキーワードを定義していませんが、 他の語彙がそれを望む可能性はあります。¶
キーワードは、現在の評価位置の外にあるインスタンスの一部を調べるために、 JSON PointerまたはRelative JSON Pointerを使用するよう定義されてもかまいません。¶
Relative JSON Pointerを使用して位置を調整できるキーワードは、 既定値が望ましい場合、現在位置を使用することを既定とすべきです。¶
このセクションで宣言されるキーワードはすべて"$"で始まり、 JSON Schemaコア語彙を構成します。これらのキーワードは、 複数の文書に分割されたものを含め、任意のスキーマまたはメタスキーマを 処理するために必要であるか、保証された相互運用性を必要とする目的のために キーワードを予約するために存在します。¶
Core語彙は、さらなる語彙の処理をブートストラップするため、 常に必須と見なされなければなりません。 使用中の語彙を宣言するために "$vocabulary"(セクション8.1)キーワードを使用する メタスキーマは、Core語彙を明示的に列挙しなければならず、 それは必須であることを示すtrueの値を持たなければなりません。¶
この語彙(かつこの語彙のみ)に対するfalse値の振る舞いは未定義であり、 "$vocabulary"が存在するがCore語彙が含まれていない場合の振る舞いも 未定義です。ただし、実装はこれらの場合を検出し、 発生時にエラーを発生させることがRECOMMENDEDです。メタスキーマが Coreを任意に使用すると宣言することには意味がありません。¶
"$vocabulary"を使用しないメタスキーマは、Core語彙のURIが trueの値で存在するかのように、Core語彙を必要とすると 見なされなければなりません。¶
Core語彙の現在のURIは次のとおりです。 <https://json-schema.org/draft/2020-12/vocab/core>。¶
対応するメタスキーマの現在のURIは次のとおりです。 https://json-schema.org/draft/2020-12/meta/core。¶
"$"接頭辞はCore語彙のために形式的に予約されているわけではありませんが、 将来の衝突の可能性を避けるため、拡張キーワード(語彙内か否かを問わず)は "$"以外の文字で始めることがRECOMMENDEDです。¶
実装にスキーマをどのように解釈するかを知らせるために、 メタスキーマと語彙という2つの概念が使用されます。 すべてのスキーマはメタスキーマを持ち、これは"$schema"キーワードを使用して 宣言できます。¶
メタスキーマは2つの目的を果たします。¶
メタスキーマは語彙と分離されており、これにより 語彙をさまざまな方法で組み合わせることができ、またメタスキーマ作成者が 特定のキーワードを禁止する、または開発およびテストサイクル中に行われることがある 通常より厳密な構文検証を行うなど、追加の制約を課すことができます。 各語彙は通常、その語彙のキーワードのみからなるメタスキーマを識別します。¶
メタスキーマの作成はJSON Schemaの高度な使用方法であるため、 メタスキーマ機能の設計は単純さよりも柔軟性を重視しています。¶
"$schema"キーワードは、JSON Schemaダイアレクト識別子としても、 それ自体がJSON Schemaであり、この特定のダイアレクト用に書かれた 有効なスキーマ集合を記述するリソースの識別子としても使用されます。¶
このキーワードの値はURI [RFC3986] (スキームを含む)でなければならず、このURIは正規化されていなければなりません。 現在のスキーマは、このURIで識別されるメタスキーマに対して有効でなければなりません。¶
このURIが取得可能なリソースを識別する場合、そのリソースは "application/schema+json"メディアタイプであるべきです。¶
"$schema"キーワードは文書ルートスキーマオブジェクトで使用すべきであり、 埋め込みスキーマリソースのルートスキーマオブジェクトで使用してもかまいません。 非リソースルートスキーマオブジェクトに現れてはなりません。文書ルートスキーマに 存在しない場合、結果としての振る舞いは実装定義です。¶
このプロパティの値は、この文書および他の文書内、ならびに他の当事者によって 別途定義されます。¶
"$vocabulary"キーワードは、メタスキーマによって記述されるスキーマで使用可能な 語彙を識別するためにメタスキーマで使用されます。 また、各語彙が必須か任意かを示すためにも使用されます。 これは、スキーマを正常に処理するには実装が必須語彙を 理解しなければならないという意味です。これらの情報は合わせて ダイアレクトを形成します。実装が理解する任意の語彙は、 その語彙に含まれる意味論的定義と一致する方法で 処理されなければなりません。¶
このキーワードの値はオブジェクトでなければなりません。オブジェクト内の プロパティ名はURI(スキームを含む)でなければならず、このURIは正規化されて いなければなりません。プロパティ名として現れる各URIは、 特定のキーワード集合とその意味論を識別します。¶
URIはURLであってもかまいませんが、取得可能なリソースの性質は 現在未定義であり、将来の使用のために予約されています。語彙作成者は、 text/htmlやtext/plainなどの人間が読めるメディアタイプでの 語彙仕様のURLを語彙URIとして使用してもかまいません。 語彙文書は今後の草案で追加される可能性があります。 現時点では、キーワード集合を識別することで十分と見なされています。 それがメタスキーマ検証とともに、現在の「語彙」が機能する方法であるためです。 将来の語彙文書形式はいずれもJSON文書として規定されるため、 当面text/htmlやその他の非JSON形式を使用しても、将来の曖昧さは生じません。 ¶
オブジェクトプロパティの値はブール値でなければなりません。 値がtrueの場合、その語彙を認識しない実装は、 このメタスキーマを"$schema"で宣言する任意のスキーマの処理を 拒否しなければなりません。値がfalseの場合、その語彙を認識しない実装は、 そのようなスキーマの処理を続行すべきです。実装が語彙を 理解している場合、値は影響を持ちません。¶
6.5に従い、認識されない キーワードは注釈として扱うべきです。 これは、認識されない語彙によって定義されるキーワードについても同様です。 現在のところ、語彙で定義された認識されないキーワードと、 どの語彙にも属さない認識されないキーワードを区別することはできません。¶
"$vocabulary"キーワードは、メタスキーマとして使用することを意図した任意の スキーマ文書のルートスキーマで使用すべきです。サブスキーマに現れてはなりません。¶
"$vocabulary"キーワードは、メタスキーマとして処理されていないスキーマ文書では 無視されなければなりません。これにより、検証器がMによって宣言された語彙を 理解することを要求せずに、メタスキーマMをその自身のメタスキーマM'に対して 検証できます。¶
"$vocabulary"が存在しない場合、実装は、参照するスキーマの "$schema"キーワードのURI値からメタスキーマが認識される場合に、 そのメタスキーマに基づいて振る舞いを決定してもかまいません。 これは、語彙が存在する以前に(Hyper-Schema使用などの)振る舞いが 認識されていた方法です。¶
スキーマによって参照されるメタスキーマが認識されない、または欠落している場合、 振る舞いは実装定義です。 実装がスキーマの処理を続行する場合、Core語彙の使用を 仮定しなければなりません。実装が特定の目的のために構築されている場合、 その目的に最も関連するすべての語彙の使用を仮定すべきです。¶
例えば、バリデーターである実装は、この仕様および関連するValidation仕様の すべての語彙の使用を仮定すべきです。¶
"$vocabulary"に関する処理制限は、"$ref"または類似のキーワードを使用して 他のメタスキーマを参照するメタスキーマが、それらの他のメタスキーマの 語彙宣言を自動的には継承しないことを意味する点に注意してください。 そのような宣言はすべて、メタスキーマとして使用することを意図した各スキーマ文書の ルートで繰り返されなければなりません。これは メタスキーマの例(付録D.2)で示されています。 この要件により、実装は各メタスキーマについて、すべての語彙要件情報を 1つの場所で見つけることができます。 スキーマの拡張性により、より細粒度のメタスキーマを参照によって組み合わせる 潜在的な方法は無限に存在するため、実装にすべての可能性を予測させ、 参照されたメタスキーマ内で語彙を検索させることは 過度に負担となります。 ¶
エラーを修正するために、更新された語彙URIおよびメタスキーマURIが 仕様草案の間に公開されてもかまいません。実装は、 この仕様草案の後で次の草案の前の日付が付いたURIを、 ここに列挙されたものと同じ構文および意味論を示すものと 見なすべきです。¶
膨大なエコシステム内でスキーマを区別するため、 スキーマはURI [RFC3986]によって識別され、 そのURIを指定することによって他のスキーマへの参照を埋め込むことができます。¶
いくつかのキーワードは、相対URI-reference [RFC3986]、 または相対URI-referenceを構築するために使用される値を受け入れることができます。 これらのキーワードでは、参照を解決するために基底URIを確立する必要があります。¶
"$id"キーワードは、スキーマリソースをその 正準 [RFC6596]URIで識別します。¶
このURIは識別子であり、必ずしもネットワークロケーターではないことに注意してください。 ネットワークでアドレス指定可能なURLの場合でも、スキーマがその正準URIから ダウンロード可能である必要はありません。¶
存在する場合、このキーワードの値は文字列でなければならず、有効な URI-reference [RFC3986]を表さなければなりません。このURI-referenceは 正規化されるべきであり、 absolute-URI [RFC3986](フラグメントなし)、 または空のフラグメントを持つURIへ解決されなければなりません。¶
空のフラグメント形式はNOT RECOMMENDEDであり、後方互換性のため、 およびapplication/schema+jsonメディアタイプが空のフラグメントを持つURIを そのフラグメントを取り除いた同じURIと同じリソースを識別するものと定義しているためにのみ 保持されています。ただし、この等価性は RFC 3986正規化プロセス [RFC3986]の一部ではないため、 実装者およびスキーマ作成者は、汎用URIライブラリがそれを 理解することに依存できません。¶
したがって、"$id"は空でないフラグメントを含んではならず、 空のフラグメントも含むべきではありません。空のフラグメントの有無にかかわらず、 absolute-URI形式を正準URIと見なさなければなりません。 古いメタスキーマは$id(以前はid)に空のフラグメントを持っているため、 空のフラグメントは現在許可されています。 将来の草案では、"$id"内の空のフラグメントさえ完全に禁止する可能性があります。 ¶
absolute-URIはまた、 RFC 3986セクション5.1.1 [RFC3986]のコンテンツに埋め込まれた基底URIに関する規定に従い、 スキーマリソース内のキーワードにおける相対URI-referenceの基底URIとしても機能します。¶
サブスキーマ内に"$id"が存在することは、そのサブスキーマが単一のスキーマ文書内の 独立したスキーマリソースを構成することを示します。さらに、 カプセル化エンティティに関するRFC 3986セクション5.1.2 [RFC3986]に従い、 サブスキーマ内の"$id"が相対URI-referenceである場合、 その参照を解決するための基底URIは親スキーマリソースのURIです。¶
親スキーマオブジェクトが"$id"によって自身をリソースとして明示的に識別していない場合、 基底URIは、前のセクション(セクション9.1.1)で示された手順によって確立される 文書全体のURIです。¶
JSON Schema文書のルートスキーマは、 absolute-URI [RFC3986](スキームを含み、 ただしフラグメントを含まない)を持つ"$id"キーワードを含むべきです。¶
JSON Pointerフラグメントを使用するには、スキーマの構造に関する知識が必要です。 再利用可能なスキーマを提供する意図でスキーマ文書を書く場合、 特定の構造的位置に結び付かないプレーン名フラグメントを使用する方が望ましい場合があります。 これにより、JSON Pointer参照を更新する必要なくサブスキーマを移動できます。¶
"$anchor"および"$dynamicAnchor"キーワードは、そのようなフラグメントを 指定するために使用されます。これらは、"$id"で見られる絶対URIではなく、 プレーン名フラグメントを作成するためにのみ使用できる識別子キーワードです。¶
結果としてのフラグメントが追加される基底URIは、問題の"$anchor"または"$dynamicAnchor"を 含むスキーマリソースの正準URIです。前のセクションで説明したように、 これは同じまたは親スキーマオブジェクト内の最も近い"$id"、または RFC 3986に従って決定される文書の基底URIです。¶
URIの通常の使用法とは別に、"$dynamicAnchor"は、 "$dynamicRef"キーワードとともに使用される場合に、そのフラグメントが拡張ポイントであることを示します。 この低レベルで高度な機能により、メタスキーマなどの再帰的スキーマを、 その拡張に特定の意味論を課すことなく、より容易に拡張できます。 詳細については、"$dynamicRef"(セクション8.2.3.2)のセクションを参照してください。¶
ほとんどの場合、通常のフラグメントの振る舞いで十分であり、 かつより直感的です。したがって、"$dynamicAnchor"が明確に必要な場合を除き、 プレーン名フラグメントを作成するためには"$anchor"を使用することがRECOMMENDEDです。¶
存在する場合、このキーワードの値は文字列でなければならず、 文字([A-Za-z])またはアンダースコア("_")で始まり、その後に任意個数の文字、 数字([0-9])、ハイフン("-")、アンダースコア("_")、およびピリオド(".")が 続かなければなりません。これはXMLの NCName生成規則 [xml-names]のUS-ASCII部分に一致します。 アンカー文字列には"#"文字が含まれないことに注意してください。 それはURI-referenceではないためです。"$anchor": "foo"はURIで使用されると フラグメント"#foo"になります。完全な例については下記を参照してください。 ¶
同じリソース内で、"$anchor"および/または"$dynamicAnchor"の任意の組み合わせを使用して 同じフラグメント名を複数回指定した場合の効果は未定義です。実装は、 そのような使用を検出した場合にエラーを発生させてもかまいません。¶
現在のインスタンス位置に適用されるスキーマを参照するために、 いくつかのキーワードを使用できます。"$ref"および"$dynamicRef"は アプリケーターキーワードであり、参照されるスキーマをインスタンスに適用します。¶
"$ref"および"$dynamicRef"の値はURI Referenceであるため、 スキーマを複数のファイルに外部化または分割することが可能になり、 自己参照を通じて再帰的構造を検証する機能を提供します。¶
これらのキーワードによって生成される解決済みURIは、必ずしもネットワーク ロケーターではなく、単なる識別子です。ネットワークでアドレス指定可能なURLであっても、 スキーマがそのアドレスからダウンロード可能である必要はなく、実装は ネットワークでアドレス指定可能なURIに遭遇したときにネットワーク操作を行うべきだと 仮定すべきではありません。¶
"$ref"キーワードは、静的に識別されたスキーマを参照するために使用される アプリケーターです。その結果は、参照されるスキーマの結果です。 結果がどのように決定されるかについてのこの定義は、 同じスキーマオブジェクト内で他のキーワードが"$ref"と並んで現れることができることを 意味する点に注意してください。 ¶
"$ref"キーワードの値は、URI-Referenceである文字列でなければなりません。 現在のURI基底に対して解決されると、適用するスキーマのURIを生成します。 この解決は、インスタンスの評価プロセスが参照の解決方法を変更できないため、 スキーマ読み込み時に安全に実行できます。¶
"$dynamicRef"キーワードは、完全な解決を実行時まで延期できるアプリケーターであり、 その時点で、インスタンスの評価中に遭遇するたびに解決されます。¶
"$dynamicAnchor"とともに、"$dynamicRef"は主に再帰的スキーマ (自身を参照するスキーマ)で有用な協調的拡張機構を実装します。 拡張ポイントと実行時に決定される拡張ターゲットの両方が"$dynamicAnchor"で定義され、 "$dynamicRef"で参照された場合にのみ実行時の動的な振る舞いを示します。¶
"$dynamicRef"プロパティの値は、URI-Referenceである文字列で なければなりません。現在のURI基底に対して解決されると、 実行時解決の開始点として使用されるURIを生成します。この初期解決は スキーマ読み込み時に安全に実行できます。¶
初期解決された開始点URIに"$dynamicAnchor"キーワードによって作成された フラグメントが含まれている場合、その初期URIは、 同名のフラグメントを"$dynamicAnchor"で定義する 動的スコープ(セクション7.1)内の 最も外側のスキーマリソースのURI(フラグメントを含む)で 置き換えられなければなりません。¶
それ以外の場合、その振る舞いは"$ref"と同一であり、実行時解決は 必要ありません。¶
これらのキーワードを使用した完全な例については、付録 Cを参照してください。 2019年以前の草案のhyper-schemaメタスキーマとこの草案との差異は、 これらのキーワードの有用性を劇的に示しています。 ¶
"$defs"キーワードは、スキーマ作成者が再利用可能なJSON Schemaを より一般的なスキーマ内にインライン化するための位置を予約します。 このキーワードは検証結果に直接影響しません。¶
このキーワードの値はオブジェクトでなければなりません。 このオブジェクトの各メンバー値は有効なJSON Schemaでなければなりません。¶
例として、"$defs"内のサブスキーマが正の整数制約である、 正の整数の配列を記述するスキーマを次に示します。¶
{
"type": "array",
"items": { "$ref": "#/$defs/positiveInteger" },
"$defs": {
"positiveInteger": {
"type": "integer",
"exclusiveMinimum": 0
}
}
}
¶
このキーワードは、スキーマ作成者からスキーマの読者または保守者へのコメントのための 位置を予約します。¶
このキーワードの値は文字列でなければなりません。実装はこの文字列を エンドユーザーに提示してはなりません。スキーマ編集用ツールは、このキーワードの表示と 編集をサポートすべきです。このキーワードの値は、スキーマを利用する開発者を 対象としたデバッグまたはエラー出力で使用してもかまいません。¶
スキーマ語彙は、語彙キーワードを含む任意のオブジェクト内で"$comment"を許可すべきです。 実装は、語彙がそれを明示的に禁止しない限り、"$comment"が許可されていると 仮定してもかまいません。語彙は、この仕様で説明されているものを超えて "$comment"のいかなる効果も指定してはなりません。¶
他のメディアタイプまたはプログラミング言語をapplication/schema+jsonへ、または application/schema+jsonから変換するツールは、そのメディアタイプまたは プログラミング言語のネイティブコメントを"$comment"値へ、または"$comment"値から 変換することを選択してもかまいません。ネイティブコメントと"$comment" プロパティの両方が存在する場合のそのような変換の振る舞いは実装依存です。¶
実装は、処理中の任意の時点で"$comment"値を削除してもかまいません。 特に、これにより、配備されるスキーマのサイズが問題となる場合に スキーマを短縮できます。¶
実装は、"$comment"プロパティの存在、不在、または内容に基づいて 他のいかなる動作も行ってはなりません。特に、"$comment"の値は 注釈結果として収集されてはなりません。¶
RFC3986セクション5.1 [RFC3986]は、文書の 既定の基底URIを決定する方法を定義します。¶
参考情報として、スキーマの初期基底URIは、それが見つかったURIです。 それがネットワーク上の場所、ローカルファイルシステム、または既知の任意のスキームのURIで 識別可能なその他の状況であるかは問いません。¶
スキーマ文書が"$id"(コンテンツに埋め込まれる)で明示的な基底URIを 定義しない場合、基底URIは RFC 3986セクション5 [RFC3986]に従って決定されるものです。¶
ソースが不明である場合、またはソースのURIスキームが不明である場合、 RFC 3986セクション5.1.4 [RFC3986]で説明されるように、適切な 実装固有の既定URIを使用してもかまいません。実装は、 仮定する任意の既定基底URIを文書化することがRECOMMENDEDです。¶
スキーマオブジェクトが別のメディアタイプの文書に埋め込まれている場合、 初期基底URIはそのメディアタイプの規則に従って決定されます。¶
以前のセクションで説明した"$id"キーワードがルートスキーマに存在しない限り、 この基底URIは、スキーマ文書のルートスキーマリソースの正準URIと 見なすべきです。¶
リモートスキーマを識別するためにURIを使用することは、必ずしも何かがダウンロードされることを 意味するわけではありません。むしろJSON Schema実装は、どのスキーマを使用するか、 およびそれらを識別するURIを事前に理解しているべきです。¶
スキーマがダウンロードされる場合、 例えば実行時までどのスキーマをダウンロードするか分からない汎用ユーザーエージェントによる場合は、 ハイパーメディアでの使用(セクション9.5.1)を参照してください。¶
実装は、バリデーターがスキーマに置く信頼に応じて、 任意のURIを任意のスキーマに関連付けること、および/またはスキーマの"$id"で与えられたURIを 自動的に関連付けることができるべきです。そのようなURIおよびスキーマは、 インスタンスの処理前に実装へ供給される場合も、スキーマ文書の処理中に 記録され、付録Aに示すように関連付けを生成する場合もあります。¶
スキーマは複数のURIを持ってもよく(そしておそらく持つでしょう)、 ただし1つのURIが複数のスキーマを識別する方法はありません。 複数のスキーマが同じURIとして識別しようとする場合、バリデーターは エラー条件を発生させるべきです。¶
実装は、あるスキーマが別のスキーマの"$schema"キーワードによって メタスキーマとして識別されたために調べられている場合、 そのスキーマをメタスキーマとして認識しなければなりません。これは、単一のスキーマ 文書が、ある時には通常のスキーマと見なされ、別の時には メタスキーマと見なされる場合があることを意味します。¶
自身のメタスキーマであるスキーマを調べる場合、 実装がそれを通常のスキーマとして処理し始めるときは、 その規則の下で処理されます。ただし、自身の"$schema"値を確認した結果として 2回目に読み込まれるときは、メタスキーマとして扱われます。したがって、 同じ文書が1つのセッションの中で両方の方法で処理されます。¶
実装は、一般的に使用されるメタスキーマを事前に読み込み、 その語彙サポート要件を事前に確認するなど、実装固有の目的のために、 スキーマをメタスキーマとして明示的に渡すことを許可してもかまいません。 メタスキーマ作成者は、そのような機能が実装間で相互運用可能であることを 期待してはなりません。¶
スキーマは、それに与えられた任意のURIによって識別できます。これには、 JSON Pointerや"$id"によって直接与えられたURIが含まれます。すべての場合において、 "$ref"参照を逆参照することは、まずその値を現在の基底URIに対して URI参照として RFC 3986 [RFC3986]に従って解決することを伴います。¶
結果としてのURIが現在の文書内、または実装に利用可能にされた 別のスキーマ文書内のスキーマを識別する場合、そのスキーマは 自動的に使用されるべきです。¶
例えば、次のスキーマを考えてください。¶
{
"$id": "https://example.net/root.json",
"items": {
"type": "array",
"items": { "$ref": "#item" }
},
"$defs": {
"single": {
"$anchor": "item",
"type": "object",
"additionalProperties": { "$ref": "other.json" }
}
}
}
¶
実装が<#/$defs/single>スキーマに遭遇すると、 "$anchor"値を現在の基底URIに対するフラグメント名として解決し、 <https://example.net/root.json#item>を形成します。¶
次に実装が<#/items>スキーマの内部を見ると、 <#item>参照に遭遇し、これを <https://example.net/root.json#item>へ解決します。これは同じ文書内で定義済みとして 見ているため、自動的に使用できます。¶
実装が"other.json"への参照に遭遇すると、 これを<https://example.net/other.json>へ解決しますが、これはこの 文書内では定義されていません。その識別子を持つスキーマが別途実装に供給されている場合、 それも自動的に使用できます。 参照されるスキーマが不明な場合、実装はどうすべきでしょうか。 自動的なネットワーク逆参照が許可される状況はあるでしょうか。 同一オリジンポリシーでしょうか。ユーザー設定可能なオプションでしょうか。 Hyper-Schemaで記述される進化するAPIの場合、新しいスキーマがシステムに 動的に追加されることが想定されるため、スキーマ文書を事前に読み込むという 絶対要件を置くことは現実的ではありません。 ¶
JSON Pointer URIフラグメントはスキーマ文書の構造に基づいて構築されるため、 埋め込みスキーマリソースとそのサブスキーマは、 その自身の正準URIに相対的なJSON Pointerフラグメント、または それを含む任意のリソースのURIに相対的なJSON Pointerフラグメントによって識別できます。¶
概念的には、リンクされたスキーマリソースの集合は、 各リソースが スキーマ参照(セクション8.2.3)で接続された別個の文書である場合でも、 1つ以上のスキーマリソースがサブスキーマとして埋め込まれた単一の文書として 構成されている場合でも、同一に振る舞うべきです。¶
親スキーマリソースのURIに相対的なJSON Pointerフラグメントを含むURIは、 埋め込みスキーマが別個の文書へ移動され参照された場合に無効になるため、 アプリケーションおよびスキーマは、そのようなURIを使用して埋め込みスキーマリソースや その内部の位置を識別するべきではありません。¶
別のスキーマリソースを内部に埋め込んだ次のスキーマ文書を 考えてください。¶
{
"$id": "https://example.com/foo",
"items": {
"$id": "https://example.com/bar",
"additionalProperties": { }
}
}
¶
URI "https://example.com/foo#/items"は、埋め込みリソースである"items"スキーマを指します。 しかし、そのスキーマリソースの正準URIは "https://example.com/bar"です。¶
その埋め込みリソース内の"additionalProperties"スキーマについて、 URI "https://example.com/foo#/items/additionalProperties"は 正しいオブジェクトを指しますが、そのオブジェクトのリソースの正準URIに相対的なURIは "https://example.com/bar#/additionalProperties"です。¶
ここで、"$ref"のURI値を使用して参照でリンクされた次の2つの スキーマリソースを考えてください。¶
{
"$id": "https://example.com/foo",
"items": {
"$ref": "bar"
}
}
{
"$id": "https://example.com/bar",
"additionalProperties": { }
}
¶
ここでは、"bar"スキーマリソースの正準URIにJSON Pointerフラグメントを追加した "https://example.com/bar#/additionalProperties"は依然として有効である一方、 "foo"スキーマリソースの正準URIにJSON Pointerフラグメントを追加することに依存していた "https://example.com/foo#/items/additionalProperties"は、もはや何にも解決されないことが 分かります。¶
また、"https://example.com/foo#/items"は両方の構成で有効ですが、 異なる値に解決されることにも注意してください。このURIは、リソースの取得URIに 似た機能を持つことになります。このURIは有効ですが、2番目の(非埋め込み)構成で "$ref"を含むオブジェクトを識別することが特に望まれる場合を除き、 埋め込みまたは参照されるリソースの"$id"を使用する方が堅牢です。¶
実装は、リソースの正準URI以外を基底とし、 それに相対的なJSON Pointerフラグメントを加えたURIによる スキーマリソース内容のアドレス指定をサポートしないことを選択してもかまいません。 したがって、スキーマ作成者はそのようなURIに依存すべきではありません。 それらを使用すると相互運用性が低下する可能性があるためです。 これは、スキーマリソースが再編成された場合に1つを除くすべてが脆弱になることを考えると、 実装がそれぞれに対する可能な基底URIとJSON Pointerフラグメントの スタック全体を追跡する必要を避けるためです。 これは簡単なので禁止する意味はないと主張する人もいれば、 スキーマ識別を複雑にするため禁止すべきだと主張する人もいます。 このトピックに関するフィードバックが推奨されます。 いくつかの議論の後、スキーマリソース境界を越えて参照するJSON Pointerについては、 "canonical"の使用を取り除き、未定義または場合によっては禁止された振る舞いとして 語る必要があると考えています (https://github.com/json-schema-org/json-schema-spec/issues/937, https://github.com/json-schema-org/json-schema-spec/issues/1183) ¶
そのような非正準URI構築のさらなる例、および代わりに使用すべき 適切な正準URIベースのフラグメントは、 付録Aで提供されています。¶
複合スキーマ文書は、輸送を容易にするために複数の埋め込みJSON Schemaリソースを 同じ文書内にまとめたJSON文書(「バンドルされた」スキーマと呼ばれることもあります)として 定義されます。¶
各埋め込みスキーマリソースは、語彙サポートの決定を含む標準的なスキーマ読み込みおよび 処理要件に従って、個別のスキーマリソースとして扱われなければなりません。¶
複合スキーマ文書を作成するためのバンドル化プロセスは、 外部スキーマリソースへの参照("$ref"など)を取り、 参照されるスキーマリソースを参照元文書内に埋め込むこととして定義されます。 バンドル化は、基底文書および任意の参照/埋め込み文書内のすべてのURI (参照に使用されるもの)を変更する必要がないように行われるべきです。¶
各埋め込みJSON Schemaリソースは、"$id"キーワードを使用してURIで自身を識別しなければならず、 スキーマリソースのルートで、使用しているダイアレクトを識別するために"$schema"キーワードを 使用すべきです。"$id"のURI識別子値は絶対URIであることがRECOMMENDEDです。¶
参照によるアプリケーターによって参照されるスキーマリソースがバンドルされる場合、 そのスキーマリソースは、含むスキーマのルートにある"$defs"オブジェクトの値として 配置されることがRECOMMENDEDです。現在埋め込まれたスキーマリソースに対する"$defs"のキーは、 バンドルされたスキーマの"$id"、またはUUIDなどのアプリケーション定義の一意識別子の 何らかの形式であってもかまいません。このキーはJSON Schema内で参照されることを 意図していませんが、バンドル化プロセスを支援するためにアプリケーションによって使用される場合があります。¶
スキーマリソースは、位置がスキーマ値として定義されている場合、 "$defs"以外の位置に埋め込まれてもかまいません。¶
バンドルされたスキーマリソースは、それが参照された元のスキーマオブジェクトを置き換えること、 またはそのスキーマリソースを他のアプリケーターキーワードで包むことによって バンドルされてはなりません。¶
同一の出力を生成するため、以前は外部にあったスキーマリソースへの 含むスキーマ文書内の参照は変更されてはならず、現在は埋め込みスキーマリソースの "$id"を使用するスキーマへ解決されます。そのような同一の出力には、検証評価および 結果としての注釈またはエラーで使用されるURIやパスが含まれます。¶
バンドル化プロセスは、多くの場合、複合スキーマ文書を作成する主な方法になりますが、 一部の文書は手作業で作成されることも可能であり、また想定されます。 その場合、個々のスキーマリソースが以前から単独で存在していない可能性もあります。¶
単一の文書内に複数のスキーマリソースが存在する場合、 どのダイアレクトで処理すべきかを定義していないスキーマリソースは、 包含するリソースと同じダイアレクトで処理されなければなりません。¶
参照可能な任意のスキーマは埋め込みも可能であるため、埋め込みスキーマリソースは 包含するリソースとは異なる"$schema"値を使用して、異なる処理ダイアレクトを 指定してもかまいません。¶
複合スキーマ文書には異なるダイアレクトを使用していると識別される埋め込みリソースが 含まれる可能性があるため、これらの文書は、メタスキーマを 複合スキーマ文書にインスタンスとして適用して検証すべきではありません。 スキーマ文書を検証するために代替の検証プロセスを提供することがRECOMMENDEDです。 各スキーマリソースは、それに関連付けられたメタスキーマに対して別々に 検証されるべきです。 検証されているものがスキーマであることが分かっている場合、 文書のルート以外で使用されたときに埋め込みリソースを識別する"$id"の使用によって、 そのスキーマが複合スキーマ文書であるかどうかを識別できます。 ¶
すべての埋め込みリソースが同じダイアレクトを使用していると識別される、 または"$schema"が省略され、そのため包含するリソースのものが既定となる 複合スキーマ文書は、適切なメタスキーマを適用して検証してもかまいません。¶
スキーマは、インスタンスに対して実行されたときに無限ループに陥ってはなりません。 例えば、"#alice"と"#bob"の2つのスキーマがどちらも相手を参照する"allOf"プロパティを 持つ場合、素朴なバリデーターはインスタンスを検証しようとして無限 再帰ループに陥る可能性があります。スキーマはこのような無限再帰的な入れ子を 使用すべきではなく、その振る舞いは未定義です。¶
サブスキーマオブジェクト(またはブール値)は、既知の アプリケーターキーワード、または1つ以上のサブスキーマを 値として取る"$defs"(セクション 8.2.4)のような位置予約キーワードとともに使用されることで 認識されます。これらのキーワードは"$defs"およびこの文書の標準アプリケーター、 既知の語彙からの拡張キーワード、または実装固有のカスタムキーワードであり得ます。¶
未知のキーワードからなる多階層構造は、"$id"の処理規則の対象となる 入れ子のサブスキーマを導入できる可能性があります。したがって、そのような認識されない 構造内に参照ターゲットを持つことは、信頼性をもって実装できず、結果としての振る舞いは 未定義です。同様に、値がスキーマでないことが分かっている既知のキーワードの下にある 参照ターゲットは、実装にそのようなターゲットを検出する必要を負わせないため、 未定義の振る舞いとなります。 これらのシナリオは、HTTPでスキーマを取得したものの、 application/schema+json以外のContent-Typeを持つ応答を受け取る場合に似ています。 実装は確かにそれをスキーマとして解釈しようとすることはできますが、 オリジンサーバーは、それが実際にそのようなものであることを 保証していません。したがって、そのように解釈することにはセキュリティ上の影響があり、 予測不能な結果を生む可能性があります。 ¶
"$defs"と同一の構文および意味論を持つ単一階層のカスタムキーワードは、 介在する"$id"キーワードを許可しないため、任意の参照ターゲットをスキーマとして 使用しようとする実装の下で正しく振る舞うことに注意してください。ただし、 この振る舞いは実装固有であり、相互運用性のために依存してはなりません。¶
JSONは、自動化APIおよびロボットのためにHTTPサーバーで広く採用されています。この セクションでは、メディアタイプと Web linking [RFC8288]をサポートするプロトコルとともに使用される場合に、 JSON文書の処理をよりRESTfulな方法で強化する方法を説明します。¶
スキーマによって記述されるインスタンスは、 Linked Data Protocol 1.0、セクション8.1 [W3C.REC-ldp-20150226]で定義される リンク関係"describedby"を使用して、ダウンロード可能なJSON Schemaへのリンクを 提供することがRECOMMENDEDです。¶
HTTPでは、そのようなリンクは Linkヘッダー [RFC8288]を使用して任意の応答に付加できます。 そのようなヘッダーの例は次のとおりです。¶
Link: <https://example.com/my-hyper-schema>; rel="describedby"
¶
ネットワーク上のハイパーメディアシステムに使用される場合、 HTTP [RFC7231]はスキーマを配布するために頻繁に選ばれるプロトコルです。 不適切に振る舞うクライアントは、スキーマを長期間キャッシュできるにもかかわらず、 必要以上に頻繁にネットワーク経由でスキーマを取得する場合、 サーバー保守者に問題を引き起こす可能性があります。¶
HTTPサーバーは、JSON Schemaに長期間有効なキャッシュヘッダーを設定すべきです。 HTTPクライアントは、キャッシュヘッダーを遵守し、その鮮度期間内は 文書を再要求すべきではありません。 分散システムは共有キャッシュおよび/またはキャッシュプロキシを使用すべきです。¶
クライアントは、JSON Schema実装またはソフトウェア製品に固有の User-Agentヘッダーを設定または先頭に追加すべきです。記号は重要度の高い順に 並ぶため、JSON Schemaライブラリ名/バージョンは、より汎用的な HTTPライブラリ名(もしあれば)に先行すべきです。例えば次のとおりです。¶
User-Agent: product-name/5.4.1 so-cool-json-schema/1.0.2 curl/7.43.0
¶
クライアントは、サーバー運用者が不適切に振る舞う可能性のあるスクリプトの所有者に 連絡できるように、"From"ヘッダーを付けて要求できるべきです。¶
このセクションでは、他の語彙の基礎として使用することがRECOMMENDEDである アプリケーターキーワードの語彙を定義します。¶
"$vocabulary"を使用しないメタスキーマは、この語彙のURIが trueの値で存在するかのように、この語彙を必要とすると 見なすべきです。¶
Applicator語彙として知られるこの語彙の現在のURIは次のとおりです。 <https://json-schema.org/draft/2020-12/vocab/applicator>。¶
対応するメタスキーマの現在のURIは次のとおりです。 https://json-schema.org/draft/2020-12/meta/applicator。¶
スキーマキーワードは通常、互いの結果に影響を与えることなく 独立して動作します。¶
スキーマ作成者の利便性のため、この語彙内のキーワードにはいくつかの 例外があります。¶
これらのキーワードは、親スキーマが適用されているインスタンス内の同じ位置に サブスキーマを適用します。それらにより、サブスキーマの結果をさまざまな方法で 結合または変更できます。¶
これらのキーワードのサブスキーマはインスタンスを完全に独立して評価するため、 そのような1つのサブスキーマの結果が兄弟サブスキーマの結果に影響してはなりません。 したがって、サブスキーマは任意の順序で適用できます。¶
これらのキーワードは、サブスキーマのブールアサーション結果を 結合または変更するための論理演算子に対応します。それらは注釈収集に 直接影響を与えませんが、同じ注釈キーワードを異なる値でインスタンス位置に 適用できるようにします。 注釈キーワードは、そのような値を結合するための独自の規則を定義します。¶
このキーワードの値は空でない配列でなければなりません。 配列の各項目は有効なJSON Schemaでなければなりません。¶
インスタンスは、このキーワードの値によって定義されるすべてのスキーマに対して 正常に検証される場合、このキーワードに対して正常に検証されます。¶
このキーワードの値は空でない配列でなければなりません。 配列の各項目は有効なJSON Schemaでなければなりません。¶
インスタンスは、このキーワードの値によって定義される少なくとも1つのスキーマに対して 正常に検証される場合、このキーワードに対して正常に検証されます。 注釈が収集されている場合、正常に検証される各サブスキーマから 注釈を収集するために、すべてのサブスキーマを調べなければならないことに注意してください。¶
このキーワードの値は空でない配列でなければなりません。 配列の各項目は有効なJSON Schemaでなければなりません。¶
インスタンスは、このキーワードの値によって定義される正確に1つのスキーマに対して 正常に検証される場合、このキーワードに対して正常に検証されます。¶
これらのキーワードのうち3つは連携して、別のサブスキーマの結果に基づく サブスキーマの条件付き適用を実装します。 4つ目は、特定の条件付きケースのショートカットです。¶
"if"、"then"、および"else"は、サブスキーマ境界を越えて 相互作用してはなりません。言い換えると、"allOf"のある 分岐内の"if"は、別の分岐内の"then"または"else"に 影響してはなりません。¶
"if"、"then"、または"else"が存在しない場合の既定の振る舞いはありません。 特に、それらは空のスキーマを伴って存在するかのように扱われてはならず、 "if"が存在しない場合、"then"と"else"はどちらも 完全に無視されなければなりません。¶
このキーワードの値は有効なJSON Schemaでなければなりません。¶
このキーワードのサブスキーマの検証結果は、全体の検証 結果に直接影響しません。むしろ、それは"then"または"else"キーワードの どちらが評価されるかを制御します。¶
このキーワードのサブスキーマに対して正常に検証される インスタンスは、存在する場合、"then"キーワードのサブスキーマ値に対しても 有効でなければなりません。¶
このキーワードのサブスキーマに対して検証に失敗する インスタンスは、存在する場合、"else"キーワードのサブスキーマ値に対しても 有効でなければなりません。¶
注釈(セクション7.7)が 収集されている場合、このキーワードが"then"または"else"なしで存在する場合を含め、 通常の方法でこのキーワードのサブスキーマから注釈が収集されます。¶
このキーワードの値は有効なJSON Schemaでなければなりません。¶
"if"が存在し、インスタンスがそのサブスキーマに対して正常に検証される場合、 そのインスタンスがこのキーワードのサブスキーマに対しても正常に検証されるなら、 このキーワードに対して検証は成功します。¶
このキーワードは、"if"が存在しない場合、またはインスタンスがそのサブスキーマに対して 検証に失敗した場合には効果を持ちません。実装は、 そのような場合、検証または注釈収集のいずれの目的においても、 インスタンスをこのキーワードに対して評価してはなりません。¶
このキーワードの値は有効なJSON Schemaでなければなりません。¶
"if"が存在し、インスタンスがそのサブスキーマに対して検証に失敗する場合、 そのインスタンスがこのキーワードのサブスキーマに対して正常に検証されるなら、 このキーワードに対して検証は成功します。¶
このキーワードは、"if"が存在しない場合、またはインスタンスがそのサブスキーマに対して 正常に検証される場合には効果を持ちません。実装は、 そのような場合、検証または注釈収集のいずれの目的においても、 インスタンスをこのキーワードに対して評価してはなりません。¶
このキーワードは、インスタンスがオブジェクトであり、特定のプロパティを含む場合に 評価されるサブスキーマを指定します。¶
このキーワードの値はオブジェクトでなければなりません。 オブジェクト内の各値は有効なJSON Schemaでなければなりません。¶
オブジェクトキーがインスタンス内のプロパティである場合、インスタンス全体は サブスキーマに対して検証されなければなりません。その使用は プロパティの存在に依存します。¶
このキーワードを省略した場合、空のオブジェクトと同じ振る舞いになります。¶
これらの各キーワードは、サブスキーマを子インスタンス、具体的にはオブジェクトの プロパティおよび配列項目に適用し、その結果を結合するための規則を定義します。¶
"prefixItems"の値は、有効なJSON Schemaの空でない配列でなければなりません。¶
インスタンスの各要素が、存在する場合、同じ位置のスキーマに対して 検証されるなら、検証は成功します。このキーワードは配列の長さを制約しません。 配列がこのキーワードの値より長い場合、このキーワードは一致する長さの 接頭部のみを検証します。¶
このキーワードは、このキーワードがサブスキーマを適用した最大の インデックスを注釈値として生成します。値は、"items"キーワードによって生成される場合のように、 サブスキーマがインスタンスのすべてのインデックスに適用された場合、 ブール値trueであってもかまいません。 この注釈は"items"および"unevaluatedItems"の振る舞いに影響します。¶
このキーワードを省略した場合、空の配列と同じアサーションの振る舞いになります。¶
"items"の値は有効なJSON Schemaでなければなりません。¶
このキーワードは、同じスキーマオブジェクト内の"prefixItems"キーワードの 注釈結果によって報告される"prefixItems"配列の長さより大きいインデックスにある すべてのインスタンス要素に、そのサブスキーマを適用します。 そのような注釈結果が存在しない場合、"items"はすべてのインスタンス 配列要素にそのサブスキーマを適用します。 "prefixItems"なしの"items"の振る舞いは、以前の草案における スキーマ形式の"items"の振る舞いと同一であることに注意してください。 "prefixItems"が存在する場合、"items"の振る舞いは 以前の"additionalItems"キーワードと同一です。 ¶
"items"サブスキーマがインスタンス配列内の任意の 位置に適用される場合、残りのすべての配列要素がこのキーワードの サブスキーマに対して評価済みであることを示すブール値trueの 注釈結果を生成します。この注釈はUnevaluated語彙における "unevaluatedItems"の振る舞いに影響します。¶
このキーワードを省略した場合、空のスキーマと同じアサーションの振る舞いになります。¶
実装は、"prefixItems"配列の存在とサイズを直接確認するなど、 同じ効果を生成する別の方法でこのキーワードを実装または最適化することを 選択してもかまいません。注釈収集をサポートしない実装はそうしなければなりません。¶
このキーワードの値は有効なJSON Schemaでなければなりません。¶
配列インスタンスは、その要素の少なくとも1つが与えられたスキーマに対して有効である場合、 "contains"に対して有効です。ただし、"minContains"が存在し、その値が0である場合は、 配列インスタンスは、たとえその要素のいずれも与えられたスキーマに対して有効でなくても、 "contains"キーワードに対して有効と見なされなければなりません。¶
このキーワードは、そのサブスキーマを適用したときにこのキーワードが正常に検証される インデックスの配列を、昇順で注釈値として生成します。 サブスキーマがインスタンスのすべてのインデックスに適用されたときに正常に検証される場合、 値はブール値"true"であってもかまいません。 このキーワードのスキーマが適用されるインスタンス配列が空である場合、 注釈は存在しなければなりません。¶
この注釈はUnevaluated語彙における"unevaluatedItems"の振る舞いに影響し、 Validation語彙における"minContains"および"maxContains"キーワードを 実装するためにも使用されてもかまいません。¶
他のキーワードで使用する注釈を収集するため、最初の一致が見つかった後でも、 サブスキーマはすべての配列要素に適用されなければなりません。 これは、すべての可能な注釈が収集されることを確保するためです。¶
"properties"の値はオブジェクトでなければなりません。 このオブジェクトの各値は有効なJSON Schemaでなければなりません。¶
インスタンス内にもこのキーワードの値内の名前としても現れる各名前について、 その名前に対応する子インスタンスが対応するスキーマに対して 正常に検証される場合、検証は成功します。¶
このキーワードの注釈結果は、このキーワードに一致したインスタンス プロパティ名の集合です。 この注釈は、この語彙の"additionalProperties"およびUnevaluated語彙の "unevaluatedProperties"の振る舞いに影響します。¶
このキーワードを省略した場合、空のオブジェクトと同じアサーションの振る舞いになります。¶
"patternProperties"の値はオブジェクトでなければなりません。このオブジェクトの各プロパティ名は、 ECMA-262正規表現ダイアレクトに従った有効な正規表現であるべきです。 このオブジェクトの各プロパティ値は有効なJSON Schemaでなければなりません。¶
このキーワードの値内のプロパティ名として現れる任意の正規表現に一致する 各インスタンス名について、その名前の子インスタンスが、一致する正規表現に対応する 各スキーマに対して正常に検証される場合、検証は成功します。¶
このキーワードの注釈結果は、このキーワードに一致したインスタンス プロパティ名の集合です。 この注釈は、この語彙の"additionalProperties"およびUnevaluated語彙の "unevaluatedProperties"の振る舞いに影響します。¶
このキーワードを省略した場合、空のオブジェクトと同じアサーションの振る舞いになります。¶
"additionalProperties"の値は有効なJSON Schemaでなければなりません。¶
このキーワードの振る舞いは、同じスキーマオブジェクト内の "properties"および"patternProperties"の存在と 注釈結果に依存します。 "additionalProperties"による検証は、"properties"または "patternProperties"の注釈結果のいずれにも現れないインスタンス名の 子値にのみ適用されます。¶
そのようなすべてのプロパティについて、子インスタンスが "additionalProperties"スキーマに対して検証される場合、検証は成功します。¶
このキーワードの注釈結果は、このキーワードのサブスキーマによって 検証されたインスタンスプロパティ名の集合です。 この注釈はUnevaluated語彙における"unevaluatedProperties"の 振る舞いに影響します。¶
このキーワードを省略した場合、空のスキーマと同じアサーションの振る舞いになります。¶
実装は、"properties"内の名前および"patternProperties"内のパターンを インスタンスプロパティ集合に対して直接確認するなど、同じ効果を生成する 別の方法でこのキーワードを実装または最適化することを選択してもかまいません。 注釈収集をサポートしない実装はそうしなければなりません。 このオプションを定義するにあたり、出力形式に曖昧さが生じる可能性があるようです。 その曖昧さは検証結果には影響しませんが、結果としての出力形式には影響します。 その曖昧さにより、注釈が使用されるか、draft-07と「同じ効果を生成する」 解決策が使用されるかに応じて、複数の有効な出力結果が許容されます。 失敗したスキーマからの注釈は破棄されるものと理解されています。 詳細については、私たちの [Decision Record](https://github.com/json-schema-org/json-schema-spec/tree/HEAD/adr/2022-04-08-cref-for-ambiguity-and-fix-later-gh-spec-issue-1172.md) を参照してください。 ¶
"propertyNames"の値は有効なJSON Schemaでなければなりません。¶
インスタンスがオブジェクトである場合、このキーワードは、インスタンス内のすべての プロパティ名が提供されたスキーマに対して検証されるなら検証に成功します。 スキーマが検査するプロパティ名は常に文字列であることに注意してください。¶
このキーワードを省略した場合、空のスキーマと同じ振る舞いになります。¶
これらのキーワードの目的は、隣接キーワードのいずれかの 動的スコープのサブスキーマに対して正常に評価されていない 配列項目またはオブジェクトプロパティに、スキーマ作成者が サブスキーマを適用できるようにすることです。¶
これらのインスタンス項目またはプロパティは、"anyOf"の分岐内の アサーションが失敗する場合など、1つ以上の隣接キーワードのサブスキーマに対して 正常に評価されなかった可能性があります。そのような失敗した評価は、 その項目またはプロパティが評価済みであるかどうかに寄与するとは見なされません。 正常な評価のみが考慮されます。¶
配列内の項目またはオブジェクトプロパティが「正常に評価」された場合、 それは論理的に、そのオブジェクトまたは配列に期待される表現の観点で 有効であると見なされます。例えば、サブスキーマが車を表しており、 2〜4個の車輪を要求する場合に、"wheels"の値が6であれば、そのインスタンス オブジェクトは車として「評価」されず、"wheels"プロパティは 「(既知のものとして正常には)未評価」と見なされ、注釈を保持しません。¶
隣接キーワードとは同じスキーマオブジェクト内のキーワードであり、 動的スコープのサブスキーマには字句的なサブスキーマだけでなく 参照ターゲットも含まれることを思い出してください。¶
これらのキーワードの振る舞いは、検証されているインスタンス位置に適用される 隣接キーワードの注釈結果に依存します。¶
"$vocabulary"を使用しないメタスキーマは、この語彙のURIが trueの値で存在するかのように、この語彙を必要とすると 見なすべきです。¶
Unevaluated Applicator語彙として知られる、この語彙の現在のURIは 次のとおりです。 <https://json-schema.org/draft/2020-12/vocab/unevaluated>。¶
対応するメタスキーマの現在のURIは次のとおりです。 https://json-schema.org/draft/2020-12/meta/unevaluated。¶
スキーマキーワードは通常、互いの結果に影響を与えることなく 独立して動作します。ただし、この語彙内のキーワードは 注目すべき例外です。¶
"unevaluatedItems"の値は有効なJSON Schemaでなければなりません。¶
このキーワードの振る舞いは、検証されているインスタンス位置に適用される 隣接キーワードの注釈結果に依存します。 具体的には、"unevaluatedItems"キーワードに隣接している場合に それらのキーワードから生じ得る"prefixItems"、"items"、および"contains"からの 注釈です。これら3つの注釈は、"unevaluatedItems"と同様に、 すべての隣接する その場アプリケーター(セクション10.2)キーワードからも 生じ得ます。 これには、この文書で定義されるその場アプリケーターが含まれますが、 それらに限定されません。¶
関連する注釈が存在しない場合、"unevaluatedItems" サブスキーマは配列内のすべての位置に適用されなければなりません。 関連する注釈のいずれかからブール値trueが存在する場合、 "unevaluatedItems"は無視されなければなりません。そうでない場合、 サブスキーマは、"contains"の注釈値のいずれにも現れない、 "prefixItems"の最大注釈値より大きい任意のインデックスに 適用されなければなりません。¶
これは、このキーワードを評価できるようになる前に、 "prefixItems"、"items"、"contains"、およびすべてのその場 アプリケーターが評価されなければならないことを意味します。 拡張キーワードの作成者は、このキーワードの後に評価される必要がある その場アプリケーターを定義してはなりません。¶
"unevaluatedItems"サブスキーマがインスタンス配列内の任意の 位置に適用される場合、"items"の振る舞いと同様に、 ブール値trueの注釈結果を生成します。 この注釈は親スキーマ内の"unevaluatedItems"の振る舞いに影響します。¶
このキーワードを省略した場合、空のスキーマと同じアサーションの振る舞いになります。¶
"unevaluatedProperties"の値は有効なJSON Schemaでなければなりません。¶
このキーワードの振る舞いは、検証されているインスタンス位置に適用される 隣接キーワードの注釈結果に依存します。 具体的には、"unevaluatedProperties"キーワードに隣接している場合に それらのキーワードから生じ得る"properties"、"patternProperties"、 および"additionalProperties"からの注釈です。これら 3つの注釈は、"unevaluatedProperties"と同様に、 すべての隣接する その場アプリケーター(セクション10.2)キーワードからも 生じ得ます。 これには、この文書で定義されるその場アプリケーターが含まれますが、 それらに限定されません。¶
"unevaluatedProperties"による検証は、検証されているインスタンス位置に適用される "properties"、"patternProperties"、"additionalProperties"、または "unevaluatedProperties"の注釈結果に現れないインスタンス名の 子値にのみ適用されます。¶
そのようなすべてのプロパティについて、子インスタンスが "unevaluatedProperties"スキーマに対して検証される場合、検証は成功します。¶
これは、このキーワードを評価できるようになる前に、 "properties"、"patternProperties"、"additionalProperties"、 およびすべてのその場アプリケーターが評価されなければならないことを意味します。 拡張キーワードの作成者は、このキーワードの後に評価される必要がある その場アプリケーターを定義してはなりません。¶
このキーワードの注釈結果は、このキーワードのサブスキーマによって 検証されたインスタンスプロパティ名の集合です。 この注釈は親スキーマ内の"unevaluatedProperties"の振る舞いに影響します。¶
このキーワードを省略した場合、空のスキーマと同じアサーションの振る舞いになります。¶
JSON Schemaはプラットフォーム非依存として定義されています。そのため、 プラットフォーム間の互換性を高めるため、実装は標準の検証出力 形式に適合するべきです。このセクションでは、利用者が検証結果を 適切に解釈するために必要となる最小要件を説明します。¶
JSON Schema出力は、セクション4.2.1で説明されるJSON Schemaデータインスタンスモデルを使用して 定義されます。実装は、それぞれの特定の言語およびプラットフォームで サポートされる範囲でこれから逸脱してもかまいませんが、出力は シリアル化またはその他の手段によってここで定義されるJSON形式へ 変換可能であることがRECOMMENDEDです。¶
この仕様は4つの出力形式を定義します。各形式の要件については、 「出力構造」セクションを参照してください。¶
実装は、"flag"、"basic"、または"detailed"形式の少なくとも1つを 提供するべきであり、"verbose"形式を提供してもかまいません。 "detailed"または"verbose"形式の1つ以上を提供する場合、 "flag"形式も提供しなければなりません。 実装は、どの形式をサポートするかを文書で指定すべきです。¶
単純な"flag"出力を超える追加情報は、スキーマまたはインスタンスの デバッグを支援するために有用です。各サブ結果は、少なくとも このセクションに含まれる情報を含むべきです。¶
これらの構成要素をすべて含む単一のオブジェクトは、 出力単位と見なされます。¶
実装は追加情報を提供することを選択してもかまいません。¶
検証パスに従う検証キーワードの相対位置です。値は JSON Pointerとして表現されなければならず、"$ref"や"$dynamicRef"などの 参照によるアプリケーターを含まなければなりません。¶
/properties/width/$ref/minimum¶
このポインターは、これらの参照によるアプリケーターキーワードを含むため、 通常のJSON Pointerプロセスでは解決できない場合があることに注意してください。¶
この情報のJSONキーは"keywordLocation"です。¶
検証キーワードの、逆参照済みの絶対位置です。値は、関連するスキーマリソースの 正準URIにJSON Pointerフラグメントを付けた完全なURIとして 表現されなければならず、"$ref"や"$dynamicRef"などの参照による アプリケーターを非終端パス構成要素として含んではなりません。 解決できない参照など、そのキーワードに関するエラーまたは注釈である場合は、 そのようなキーワードで終わってもかまいません。 ここでの"absolute"は、RFC 3986の"absolute-URI" 用語(スキームを持つがフラグメントを持たないという意味)ではなく、 「絶対ファイルシステムパス」(完全な位置を意味する)という意味であることに 注意してください。キーワード絶対位置は、キーワードを識別するために フラグメントを持ちます。 ¶
https://example.com/schemas/common#/$defs/count/minimum¶
この情報は、動的スコープが参照を越えなかった場合、またはスキーマが "$id"として絶対URIを宣言していない場合にのみ省略してもかまいません。¶
この情報のJSONキーは"absoluteKeywordLocation"です。¶
検証されているインスタンス内のJSON値の位置です。 値はJSON Pointerとして表現されなければなりません。¶
この情報のJSONキーは"instanceLocation"です。¶
検証によって生成されるエラーまたは注釈です。¶
エラーについては、メッセージの具体的な文言はこの仕様では定義されません。 実装がこれを提供する必要があります。¶
注釈については、注釈を生成する各キーワードがその形式を指定します。 既定では、それはキーワードの値です。¶
失敗した検証に対するJSONキーは"error"であり、成功した検証に対しては "annotation"です。¶
2つの階層構造では、このプロパティは入れ子のエラーおよび注釈を保持します。¶
失敗した検証における入れ子の結果のJSONキーは"errors"であり、 成功した検証では"annotations"です。入れ子の結果を持つキーワードは ローカルなエラーまたは注釈も持てるため、複数形であることに注意してください。¶
出力は、"valid"という名前のブールプロパティを含むオブジェクトでなければなりません。 結果に関する追加情報が必要な場合、出力は以下で説明するように "errors"または"annotations"も含まなければなりません。¶
これらの例では、次のスキーマとインスタンスを使用します。¶
{
"$id": "https://example.com/polygon",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$defs": {
"point": {
"type": "object",
"properties": {
"x": { "type": "number" },
"y": { "type": "number" }
},
"additionalProperties": false,
"required": [ "x", "y" ]
}
},
"type": "array",
"items": { "$ref": "#/$defs/point" },
"minItems": 3
}
[
{
"x": 2.5,
"y": 1.3
},
{
"x": 1,
"z": 6.7
}
]
¶
このインスタンスは検証に失敗してエラーを生成しますが、 注釈を生成する合格スキーマの例を推測するのは容易です。¶
具体的には、生成されるエラーは次のとおりです。¶
これらの例に示されているエラーメッセージの文言は、 この仕様の要件ではないことに注意してください。実装は、対象読者に合わせた エラーメッセージを作成するか、ユーザーが独自のメッセージを作成できる テンプレート機構を提供すべきです。¶
最も単純な場合、"valid"プロパティに対するブール結果だけを 満たせば十分です。¶
{
"valid": false
}
¶
この形式ではエラーや注釈が返されないため、結果が決定でき次第、 失敗または成功を返すために実装が短絡ロジックを使用することが RECOMMENDEDです。例えば、"anyOf"キーワードが5つのサブスキーマを含み、 2番目が合格する場合、残り3つを確認する必要はありません。ロジックは単に 成功として返ることができます。¶
"Basic"構造は、出力単位の平坦なリストです。¶
{
"valid": false,
"errors": [
{
"keywordLocation": "",
"instanceLocation": "",
"error": "A subschema had errors."
},
{
"keywordLocation": "/items/$ref",
"absoluteKeywordLocation":
"https://example.com/polygon#/$defs/point",
"instanceLocation": "/1",
"error": "A subschema had errors."
},
{
"keywordLocation": "/items/$ref/required",
"absoluteKeywordLocation":
"https://example.com/polygon#/$defs/point/required",
"instanceLocation": "/1",
"error": "Required property 'y' not found."
},
{
"keywordLocation": "/items/$ref/additionalProperties",
"absoluteKeywordLocation":
"https://example.com/polygon#/$defs/point/additionalProperties",
"instanceLocation": "/1/z",
"error": "Additional property 'z' found but was invalid."
},
{
"keywordLocation": "/minItems",
"instanceLocation": "",
"error": "Expected at least 3 items but found 2"
}
]
}
¶
"Detailed"構造はスキーマに基づいており、人間と機械の双方にとって より読みやすいものにできます。このように構造が整理されていると、 エラー間の関連がより明確になります。例えば、欠落している"y"プロパティと 余分な"z"プロパティがどちらもインスタンス内の同じ位置に由来するという事実は、 "Basic"構造ではすぐには明らかではありません。 階層内では、その相関をより容易に識別できます。¶
次の規則が結果オブジェクトの構築を支配します。¶
分岐ノードはエラーメッセージまたは注釈を必要としません。¶
{
"valid": false,
"keywordLocation": "",
"instanceLocation": "",
"errors": [
{
"valid": false,
"keywordLocation": "/items/$ref",
"absoluteKeywordLocation":
"https://example.com/polygon#/$defs/point",
"instanceLocation": "/1",
"errors": [
{
"valid": false,
"keywordLocation": "/items/$ref/required",
"absoluteKeywordLocation":
"https://example.com/polygon#/$defs/point/required",
"instanceLocation": "/1",
"error": "Required property 'y' not found."
},
{
"valid": false,
"keywordLocation": "/items/$ref/additionalProperties",
"absoluteKeywordLocation":
"https://example.com/polygon#/$defs/point/additionalProperties",
"instanceLocation": "/1/z",
"error": "Additional property 'z' found but was invalid."
}
]
},
{
"valid": false,
"keywordLocation": "/minItems",
"instanceLocation": "",
"error": "Expected at least 3 items but found 2"
}
]
}
¶
"Verbose"構造は、スキーマの階層に正確に一致する、完全に実現された 階層です。この構造は、エラーの位置が重要なフォーム生成や 検証に応用できます。¶
これと"Detailed"構造の主な違いは、すべての結果が返されることです。 これには、通常なら削除されるサブスキーマ検証結果 (例: 失敗した検証の注釈、`not`キーワード内の成功した検証など)が含まれます。 このため、各ノードにも、そのノードの検証結果を示す`valid`プロパティを 持たせることがRECOMMENDEDです。¶
この出力構造は非常に大きくなる可能性があるため、簡潔にするために ここではより小さな例を示します。上記の例の完全な出力構造のURIは 次のとおりです。 https://json-schema.org/draft/2020-12/output/verbose-example。¶
// schema
{
"$id": "https://example.com/polygon",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"validProp": true,
},
"additionalProperties": false
}
// instance
{
"validProp": 5,
"disallowedProp": "value"
}
// result
{
"valid": false,
"keywordLocation": "",
"instanceLocation": "",
"errors": [
{
"valid": true,
"keywordLocation": "/type",
"instanceLocation": ""
},
{
"valid": true,
"keywordLocation": "/properties",
"instanceLocation": ""
},
{
"valid": false,
"keywordLocation": "/additionalProperties",
"instanceLocation": "",
"errors": [
{
"valid": false,
"keywordLocation": "/additionalProperties",
"instanceLocation": "/disallowedProp",
"error": "Additional property 'disallowedProp' found but was invalid."
}
]
}
]
}
¶
便宜のため、実装によって生成された出力を検証するための JSON Schemaが提供されています。そのURIは次のとおりです。 https://json-schema.org/draft/2020-12/output/schema。¶
スキーマとインスタンスはいずれもJSON値です。そのため、 RFC 8259 [RFC8259]で定義されるすべてのセキュリティ上の考慮事項が適用されます。¶
インスタンスとスキーマはいずれも、信頼されていない第三者によって書かれ、 公開インターネットサーバーに配備されることが頻繁にあります。 バリデーターは、スキーマの解析およびそれに対する検証が過度の システムリソースを消費しないよう注意すべきです。 バリデーターは無限ループに陥ってはなりません。¶
悪意のある当事者は、実装に非常に大きな値のコピーを注釈として 繰り返し収集させる可能性があります。実装は、このようなシナリオにおける システムリソースの過度な消費を防ぐべきです。¶
サーバーは、既存または非常によく似た"$id"を持つスキーマをアップロードすることによって、 悪意のある当事者が既存のスキーマの機能を変更できないよう確保しなければなりません。¶
個々のJSON Schema語彙にも、それぞれ独自のセキュリティ上の考慮事項が 存在する可能性があります。詳細については、それぞれの仕様を参照してください。¶
スキーマ作成者は"$comment"の内容に注意すべきです。悪意のある 実装は、仕様に違反してそれをエンドユーザーに表示したり、 そのような振る舞いが期待される場合でもそれを削除しなかったりする可能性があるためです。¶
悪意のあるスキーマ作成者は、実行可能コードまたはその他の危険な 材料を"$comment"内に置く可能性があります。実装は、"$comment"の内容に基づいて 解析したりその他の動作を行ったりしてはなりません。¶
JSON Schemaのために提案されるMIMEメディアタイプは、次のように定義されます。¶
JSON Schema固有のメディアタイプを必要とするJSON Schemaインスタンスのために 提案されるMIMEメディアタイプは、次のように定義されます。¶
次のスキーマを考えてください。これは、"$id"がルートスキーマと さまざまなサブスキーマの両方を識別するために使用され、 "$anchor"がプレーン名フラグメント識別子を定義するために 使用されていることを示しています。¶
{
"$id": "https://example.com/root.json",
"$defs": {
"A": { "$anchor": "foo" },
"B": {
"$id": "other.json",
"$defs": {
"X": { "$anchor": "bar" },
"Y": {
"$id": "t/inner.json",
"$anchor": "bar"
}
}
},
"C": {
"$id": "urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f"
}
}
}
¶
次のURIエンコードされたJSON Pointer [RFC6901](ルートスキーマに対する相対) にあるスキーマは、次の 基底URIを持ち、上記のセクション5および 9.2.1に従って、 列挙された任意のURIで識別できます。¶
注記: URIのフラグメント部分がそれを正準または非正準にするのではなく、 使用される基底URI(任意のフラグメントを含む完全なURIの一部として)が、 結果としての完全なURIの正準性を決定します。 複数の「正準」URIでしょうか。これが混乱を招く可能性があることを認めます。 さらなるコメントについては、 JSON Pointerフラグメントと埋め込みスキーマリソース(セクション9.2.1) セクションにあるCREFを読むことをお勧めします。 ¶
参照("$ref")がどのように、どこに現れるかに基づいてスキーマ文書を 再配置するためのさまざまなツールが作成されています。この付録では、 どのユースケースと操作がこの仕様に適合するかを説明します。¶
一緒に使用することを意図したスキーマリソースの集合は、 それぞれが独自のスキーマ文書にある形、すべてが同じスキーマ文書にある形、 またはその中間の任意の粒度の文書グループ化で編成できます。¶
参照除去のさまざまな種類を実行するための多くのツールが存在します。 その一般的なケースは、すべての参照をそのファイル内で解決できる 単一ファイルを生成することです。これは通常、配布を簡素化するため、 またはJSON Schemaライブラリのさまざまな呼び出しが大量のリソースを 追跡して読み込む必要がないよう、コーディングを簡素化するために行われます。¶
この変換は、すべての静的参照(例: "$ref")が、正準リソースURIを 基底として使用するURIへ解決されるURI参照を使用し、かつすべてのスキーマ リソースがそのルートスキーマ内の"$id"としてabsolute-URIを持つ限り、 安全かつ可逆的に行うことができます。¶
これらの条件が満たされていれば、各外部リソースは"$defs"の下に コピーでき、リソースのスキーマオブジェクト間の参照を壊すことなく、 また検証または注釈結果のいかなる側面も変更せずに済みます。 "$defs"の下のスキーマ名は、それぞれが一意であると仮定すれば、 埋め込みリソースの正準URIには現れないため、振る舞いに影響しません。¶
すべての参照を除去して単一のスキーマ文書を生成しようとしても、 すべての場合において、元の形式と同一の振る舞いを持つスキーマが 生成されるわけではありません。¶
"$ref"は現在、他のキーワードと同様に扱われ、同じスキーマオブジェクト内で 他のキーワードが許可されているため、すべての場合に非再帰的な"$ref"除去を 完全にサポートするには、比較的複雑なスキーマ操作が必要になる場合があります。 安全な"$ref"除去変換の集合を決定または提供することは、この仕様の範囲外です。 それらはスキーマ構造だけでなく、意図された使用方法にも依存するためです。¶
単純な再帰的ツリー構造を記述する次の2つのスキーマを考えてください。 ツリー内の各ノードは任意の型の"data"フィールドを持つことができます。 最初のスキーマは他のインスタンスプロパティを許可し無視します。 2番目はより厳密で、"data"および"children"プロパティのみを許可します。 "data"を"daat"と誤記した例インスタンスも示しています。¶
// tree schema, extensible
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/tree",
"$dynamicAnchor": "node",
"type": "object",
"properties": {
"data": true,
"children": {
"type": "array",
"items": {
"$dynamicRef": "#node"
}
}
}
}
// strict-tree schema, guards against misspelled properties
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/strict-tree",
"$dynamicAnchor": "node",
"$ref": "tree",
"unevaluatedProperties": false
}
// instance with misspelled field
{
"children": [ { "daat": 1 } ]
}
¶
これら2つのスキーマを読み込むと、それぞれに存在する "node"という名前の"$dynamicAnchor"(これは単なる名前なので"#"がないことに注意) に気付き、その結果、次の完全なスキーマURIが得られます。¶
さらに、JSON Schema実装は、これらのフラグメントが "$dynamicAnchor"で作成されたという事実を追跡します。¶
"strict-tree"スキーマをインスタンスに適用すると、"$ref"をたどって "tree"スキーマへ進み、その"children"サブスキーマを調べ、 その"items"サブスキーマ内に"#node"への"$dynamicRef"を見つけます (URIフラグメント構文のための"#"に注意)。その参照は "https://example.com/tree#node"へ解決されます。これは "$dynamicAnchor"によって作成されたフラグメントを持つURIです。 したがって、参照をたどる前に動的スコープを調べなければなりません。¶
この時点で、動的パスは "#/$ref/properties/children/items/$dynamicRef"であり、動的スコープには (最も外側のスコープから最も内側のスコープへ)次が含まれます。¶
ここでは、スキーマリソース内のどこでも定義可能なプレーン名フラグメントを 探しているため、JSON Pointerフラグメントはこの確認には関係ありません。 つまり、それらのフラグメントを削除し、連続する重複を取り除いて、 次を生成できます。¶
この場合、最も外側のリソースにも"$dynamicAnchor"によって定義された "node"フラグメントがあります。したがって、"$dynamicRef"を "https://example.com/tree#node"へ解決する代わりに、 "https://example.com/strict-tree#node"へ解決します。¶
このようにすると、"tree"スキーマ内の再帰は、"strict-tree"を インスタンスルートにのみ適用し、インスタンスの子には"tree"を適用するのではなく、 "strict-tree"のルートへ再帰します。¶
この例では、両方の"$dynamicAnchor"が各スキーマ内の同じ場所、 具体的にはリソースルートスキーマにあることを示しています。 プレーン名フラグメントはJSON構造から独立しているため、 一方または両方のノードスキーマオブジェクトが"$defs"の下へ移動されていても、 同じように機能します。動的参照をどのように解決するかを知らせるのは、 JSON構造内の何らかの対応関係ではなく、一致する"$dynamicAnchor"値です。¶
語彙作成者は、その語彙が広範な使用を意図し、 かつ他の語彙と組み合わせられる可能性がある場合、キーワード名の衝突を 避けるよう注意すべきです。JSON Schemaは形式的な名前空間システムを 提供しませんが、キーワード名も制約しないため、任意の数の 名前空間化アプローチを可能にします。¶
語彙は、別の語彙のキーワードの振る舞いに関して自身のキーワードの 振る舞いを定義したり、別の語彙のキーワードを許容値の集合を 制限または拡張して使用したりするなど、互いに基づいて構築できます。 そのようなすべての語彙再利用が、その基になる語彙と互換性のある 新しい語彙を生じるとは限りません。語彙作成者は、どの程度の互換性が 期待されるのか、もしあれば、それを明確に文書化すべきです。¶
メタスキーマ作成者は、同じキーワードに対して競合する構文または意味論を 定義する複数の語彙を組み合わせるために"$vocabulary"を使用すべきではありません。 意味論的な競合は一般にスキーマ検証を通じて検出できないため、 実装にそのような競合の検出は期待されません。競合する語彙が宣言された場合、 結果としての振る舞いは未定義です。¶
語彙作成者は、その語彙のキーワードの期待される使用方法を 単独で検証するメタスキーマを提供すべきです。そのようなメタスキーマは 追加キーワードを禁止すべきではなく、Core語彙のいかなる キーワードも禁止してはなりません。¶
メタスキーマ作成者は、各語彙のメタスキーマを "allOf"(セクション10.2.1.1)キーワードを使用して 参照することが推奨されますが、特定のユースケースでは メタスキーマを構築する他の仕組みが適切である場合もあります。¶
メタスキーマの再帰的な性質により、"$dynamicAnchor"および"$dynamicRef"キーワードは、 Validationメタスキーマを拡張するJSON Hyper-Schemaメタスキーマに見られるように、 既存のメタスキーマを拡張するために特に有用です。¶
メタスキーマは、宣言された語彙に関連付けられたメタスキーマが記述する内容を超えて、 追加の制約を課してもかまいません。これには、どの語彙にも存在しない キーワードを記述することも含まれます。これにより、語彙のサブセットへの 使用制限や、再利用を意図しないローカルに定義されたキーワードの検証が可能になります。¶
ただし、メタスキーマは、語彙が期待するものとは異なるJSON型を要求するなど、 自身が宣言するいかなる語彙とも矛盾すべきではありません。 結果としての振る舞いは未定義です。¶
任意の実装における語彙サポートをテストする必要がない、 ローカル使用を意図したメタスキーマは、"$vocabulary"を完全に省略しても 安全です。¶
このメタスキーマは、Core語彙とApplicator語彙の両方を 拡張語彙とともに明示的に宣言し、それらのメタスキーマを "allOf"で組み合わせます。その語彙内のキーワードのみを記述する 拡張語彙のメタスキーマは、主な例のメタスキーマの後に示されます。¶
主な例のメタスキーマは、"unevaluated"で始まるキーワードを禁止することで、 Unevaluated語彙の使用も制限します。これらのキーワードは実装が 特に複雑です。これは他の語彙によって定義される意味論やキーワード集合を 変更しません。このメタスキーマを使用するスキーマが "unevaluated"で始まるキーワードを使用しようとすると、 このメタスキーマに対する検証に失敗することを確実にするだけです。¶
最後に、このメタスキーマは、どの語彙にも属さないキーワード "localKeyword"の構文を記述します。おそらく、このメタスキーマの 実装者と利用者は"localKeyword"の意味論を理解しているでしょう。 JSON Schemaは、語彙の外でキーワード意味論を表現する仕組みを 定義しないため、それらは理解されている特定の環境を除いて 使用には適しません。¶
このメタスキーマは、一般的な使用のために複数の語彙を組み合わせます。¶
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/meta/general-use-example",
"$dynamicAnchor": "meta",
"$vocabulary": {
"https://json-schema.org/draft/2020-12/vocab/core": true,
"https://json-schema.org/draft/2020-12/vocab/applicator": true,
"https://json-schema.org/draft/2020-12/vocab/validation": true,
"https://example.com/vocab/example-vocab": true
},
"allOf": [
{"$ref": "https://json-schema.org/draft/2020-12/meta/core"},
{"$ref": "https://json-schema.org/draft/2020-12/meta/applicator"},
{"$ref": "https://json-schema.org/draft/2020-12/meta/validation"},
{"$ref": "https://example.com/meta/example-vocab"}
],
"patternProperties": {
"^unevaluated": false
},
"properties": {
"localKeyword": {
"$comment": "Not in vocabulary, but validated if used",
"type": "string"
}
}
}
¶
このメタスキーマは、単一の拡張語彙のみを記述します。¶
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/meta/example-vocab",
"$dynamicAnchor": "meta",
"$vocabulary": {
"https://example.com/vocab/example-vocab": true,
},
"type": ["object", "boolean"],
"properties": {
"minDate": {
"type": "string",
"pattern": "\d\d\d\d-\d\d-\d\d",
"format": "date",
}
}
}
¶
上に示すように、汎用メタスキーマの"allOf"で参照される 各単一語彙メタスキーマが、それぞれ対応する語彙を宣言しているにもかかわらず、 この新しいメタスキーマではそれらを再宣言しなければなりません。¶
Core仕様およびValidation仕様で定義されるすべての語彙を組み合わせる 標準メタスキーマと、それらの仕様およびHyper-Schema仕様で定義される すべての語彙を組み合わせる標準メタスキーマは、追加の複雑な組み合わせを 示しています。これらのメタスキーマのURIは、それぞれValidation仕様および Hyper-Schema仕様で見つけることができます。¶
汎用メタスキーマは"minDate"の構文を検証できますが、 "minDate"の意味論的な意味の背後にあるロジックを定義するのは語彙です。 意味論を理解していなければ(この例では、インスタンス値がスキーマ内の キーワード値として提供された日付と等しいか、それ以後の日付でなければならないこと)、 実装は構文上の使用方法しか検証できません。この場合、それは 日付形式の文字列であることを検証することを意味します (Validation仕様 [json-schema-validation]で説明されるように、 "format"が純粋に注釈として機能する場合でも検証されることを 確保するために"pattern"を使用します)。¶
参照の存在は検証結果に対して透過的であることが期待されますが、 コードジェネレーターやUIレンダラーなどの生成的なユースケースでは、 参照が意味論的に重要であると見なされることがよくあります。¶
そのようなユースケース固有の意味論を明示するためのベストプラクティスは、 "$ref"などの参照キーワードと同じスキーマオブジェクト内で使用する 注釈キーワードを作成することです。¶
例えば、コードジェネレーターが参照ターゲットを別個のクラスと見なすべきか、 またそれらのクラスがどのように関連するかを決定するための仮想的なキーワードを 次に示します。この例は説明のみを目的としており、 機能するコード生成キーワードを提案することを意図していないことに注意してください。¶
{
"allOf": [
{
"classRelation": "is-a",
"$ref": "classes/base.json"
},
{
"$ref": "fields/common.json"
}
],
"properties": {
"foo": {
"classRelation": "has-a",
"$ref": "classes/foo.json"
},
"date": {
"$ref": "types/dateStruct.json",
}
}
}
¶
ここでは、このスキーマは何らかのオブジェクト指向クラスを表します。 "allOf"内の最初の参照は基底クラスとして注記されています。 2番目にはクラス関係が割り当てられていません。つまり、コードジェネレーターは、 参照が関与していないかのように、ターゲットの定義をこの定義と 組み合わせるべきであることを意味します。¶
propertiesを見ると、"foo"はオブジェクト合成としてフラグ付けされていますが、 "date"プロパティはそうではありません。これは別個のクラスのインスタンスではなく、 単にサブフィールドを持つフィールドです。¶
この形式の使用では、注釈が参照と同じオブジェクト内にあり、 その参照が参照として認識可能である必要があります。¶
JSON Schemaの初期草案に取り組んでくださった Gary Court、 Francis Galiegue、 Kris Zyp、 およびGeraint Luffに感謝します。¶
文書への提出およびパッチを寄せてくださった Jason Desrosiers、 Daniel Perrett、 Erik Wilde、 Evgeny Poberezkin、 Brad Bowman、 Gowry Sankar、 Donald Pipowitch、 Dave Finlay、 Denis Laxalde、 Phil Sturgeon、 Shawn Silverman、 およびKaren Etheridgeに感謝します。¶
このセクションはInternet-Draftステータスを離れる前に削除されます。¶