インターネットドラフト JSON スキーマ 2022年6月
ライトら 2022年12月18日 失効 [ページ]
ワーキンググループ
インターネットエンジニアリングタスクフォース
インターネットドラフト
draft-bhutton-json-schema-01
公開
意図されたステータス
情報提供
失効
著者
A. ライト、
H. アンドリュース、
B. ハットン、
ポストマン
G. デニス

JSON スキーマ: JSON ドキュメントを記述するためのメディアタイプ

要約

JSON スキーマは、JSON データの構造を記述するための JSON ベースのフォーマットであるメディアタイプ "application/schema+json" を定義します。JSON スキーマは、JSON ドキュメントがどのようなものであるべきか、そこから情報を抽出する方法、そしてどのように操作するかを主張します。「application/schema-instance+json」メディアタイプは、「application/json」ドキュメントに対して提供できるもの以上の、"application/schema+json" との機能豊富な統合を提供します。

読者への注意

このドラフトの課題リストは、https://github.com/json-schema-org/json-schema-spec/issues で確認できます。

詳細については、https://json-schema.dokyumento.jp/ を参照してください。

フィードバックを提供するには、この課題トラッカー、ホームページに記載されているコミュニケーション方法、またはドキュメント編集者へのメールを使用してください。

このメモのステータス

このインターネットドラフトは、BCP 78 および BCP 79 の規定に完全に準拠して提出されています。

インターネットドラフトは、インターネットエンジニアリングタスクフォース(IETF)の作業文書です。他のグループもインターネットドラフトとして作業文書を配布する場合があることに注意してください。現在のインターネットドラフトのリストは、https://datatracker.ietf.org/drafts/current/にあります。

インターネットドラフトは、最大6ヶ月間有効なドラフト文書であり、いつでも他の文書によって更新、置換、または廃止される可能性があります。「進行中の作業」以外に、インターネットドラフトを参照資料として使用したり、引用したりすることは適切ではありません。

このインターネットドラフトは、2022年12月18日に失効します。

目次

1. はじめに

JSON Schemaは、JSONデータの構造を定義するためのJSONメディアタイプです。JSON Schemaは、JSONデータの検証、ドキュメント化、ハイパーリンクナビゲーション、およびインタラクション制御を定義することを目的としています。

この仕様では、別のJSON Schemaへの参照の指定、JSON Schema参照の逆参照、使用されている方言の指定、方言のボキャブラリ要件の指定、および期待される出力の定義など、JSON Schemaのコア用語とメカニズムを定義します。

他の仕様では、検証、リンク、アノテーション、ナビゲーション、およびインタラクションに関するアサーションを実行するボキャブラリを定義しています。

2. 表記規則と用語

このドキュメントにおけるキーワード「MUST」、「MUST NOT」、「REQUIRED」、「SHALL」、「SHALL NOT」、「SHOULD」、「SHOULD NOT」、「RECOMMENDED」、「MAY」、「OPTIONAL」は、RFC 2119 [RFC2119]で説明されているように解釈されます。

このドキュメントにおける用語「JSON」、「JSONテキスト」、「JSON値」、「メンバ」、「要素」、「オブジェクト」、「配列」、「数値」、「文字列」、「ブール値」、「true」、「false」、「null」は、RFC 8259 [RFC8259]で定義されているように解釈されます。

3. 概要

このドキュメントでは、JSONデータを記述するためのJSON Schemaを識別する新しいメディアタイプ「application/schema+json」を提案しています。また、追加の統合機能を提供するためのさらにオプションのメディアタイプ「application/schema-instance+json」も提案しています。JSON Schemaはそれ自体がJSONドキュメントです。これと関連する仕様では、作成者がいくつかの方法でJSONデータを記述できるようにするキーワードを定義しています。

JSON Schemaは、キーワードを使用してJSONインスタンスに対する制約を主張したり、追加情報を使用してそれらのインスタンスに注釈を付けたりします。追加のキーワードは、より複雑なJSONデータ構造にアサーションとアノテーションを適用する場合、または何らかの条件に基づいて適用する場合に使用されます。

再利用を容易にするために、キーワードをボキャブラリに編成できます。ボキャブラリは、キーワードのリストと、その構文とセマンティクスで構成されます。方言は、メタスキーマで識別されたボキャブラリのセットとその必要なサポートとして定義されます。

JSON Schemaは、追加のボキャブラリを定義するか、またはより非公式に、ボキャブラリの外部に追加のキーワードを定義することで拡張できます。認識されない個々のキーワードは、単にアノテーションとして値が収集されるだけであり、認識されないボキャブラリに関する動作は、使用中のボキャブラリを宣言する際に制御できます。

このドキュメントでは、実装によってサポートされる必要があるコアボキャブラリを定義しており、無効にすることはできません。そのキーワードはそれぞれ「$」文字で接頭辞が付けられ、必須であることを強調しています。このボキャブラリは「application/schema+json」メディアタイプの機能に不可欠であり、他のボキャブラリのロードをブートストラップするために使用されます。

さらに、このドキュメントでは、サブスキーマを条件付きで適用するため、およびオブジェクトと配列の内容にサブスキーマを適用するための推奨されるキーワードのボキャブラリを定義しています。これらのスキーマがアサーション検証、アノテーション、またはその両方を目的としている場合でも、重要ではないJSONインスタンスのスキーマを作成するには、このボキャブラリまたはそれと非常によく似たボキャブラリが必要です。必須のコアボキャブラリの一部ではありませんが、最大の相互運用性を確保するために、この追加のボキャブラリはここに含まれており、その使用を強くお勧めします。

構造検証やハイパーメディアアノテーションなどの目的のためのさらなるボキャブラリは、他のドキュメントで定義されています。これらの他のドキュメントはそれぞれ、そのドキュメントの目的に合ったスキーマを作成するために必要な標準的なボキャブラリセットを収集する方言を定義しています。

4. 定義

4.1. JSONドキュメント

JSONドキュメントは、application/jsonメディアタイプによって記述された情報リソース(一連のオクテット)です。

JSON Schemaでは、それが定義するデータモデルのために、「JSONドキュメント」、「JSONテキスト」、「JSON値」という用語は互換性があります。

JSON SchemaはJSONドキュメントに対してのみ定義されています。ただし、JSON Schemaデータモデルに従って解析または処理できるドキュメントやメモリ構造は、CBOR [RFC7049]のようなメディアタイプを含め、JSON Schemaに対して解釈できます。

4.2. インスタンス

スキーマが適用されるJSONドキュメントは、「インスタンス」と呼ばれます。

JSON Schemaは、「application/json」または互換性のあるドキュメント(「+json」構造化構文サフィックスを持つメディアタイプを含む)に対して定義されています。

これらのうち、この仕様では、「application/schema-instance+json」メディアタイプを定義しており、URI内のフラグメントの処理を定義しています。

4.2.1. インスタンスデータモデル

JSON Schemaは、データモデルに従ってドキュメントを解釈します。このデータモデルに従って解釈されたJSON値は、「インスタンス」と呼ばれます。

インスタンスには、6つのプリミティブタイプのいずれかがあり、タイプに応じてさまざまな値が可能です。

null
JSONの「null」値
boolean
JSONの「true」または「false」値からの「true」または「false」値
object
JSONの「object」値からの、文字列をインスタンスにマッピングするプロパティの順序付けられていないセット
array
JSONの「array」値からのインスタンスの順序付きリスト
number
JSONの「number」値からの任意精度の10進数値
string
JSONの「string」値からのUnicodeコードポイントの文字列

空白文字とフォーマットに関する懸念事項(データモデル内で等しい数値の異なる字句表現など)は、JSON Schemaの範囲外です。このような字句表現の違いを扱うことを望むJSON Schema ボキャブラリ (セクション8.1)は、元のJSON表現のUnicode文字を利用するのではなく、データモデル内でフォーマットされた文字列を正確に解釈するためのキーワードを定義する必要があります。

オブジェクトは同じキーを持つ2つのプロパティを持つことができないため、単一のオブジェクトで同じキーを持つ2つのプロパティを定義しようとするJSONドキュメントの動作は未定義です。

JSON Schemaボキャブラリは自由に独自の拡張タイプシステムを定義できることに注意してください。これは、ここで定義されているコアデータモデルタイプと混同しないでください。「integer」は、ボキャブラリがキーワードの値として定義するのに妥当なタイプですが、データモデルは整数と他の数値を区別しません。

4.2.2. インスタンスの等価性

2つのJSONインスタンスは、データモデルに従って同じ型であり、同じ値を持つ場合に限り、等しいと言われます。具体的には、これは以下のことを意味します。

  • どちらもnullである;または
  • どちらもtrueである;または
  • どちらもfalseである;または
  • どちらも文字列であり、コードポイントごとに同じである;または
  • どちらも数値であり、数学的な値が同じである;または
  • どちらも配列であり、要素ごとに等しい値を持つ;または
  • どちらもオブジェクトであり、一方のオブジェクト内の各プロパティは、もう一方のオブジェクトにキーが等しいプロパティを正確に1つ持ち、そのもう一方のプロパティは等しい値を持つ。

この定義には、配列の長さが同じでなければならないこと、オブジェクトは同じ数のメンバを持たなければならないこと、オブジェクトのプロパティは順序付けられていないこと、同じキーを持つ複数のプロパティを定義する方法がないこと、そして単なるフォーマットの違い(インデント、コンマの位置、末尾のゼロ)は重要ではないことが含まれています。

4.2.3. 非JSONインスタンス

JSONスキーマを、JSONスキーマデータモデルのスーパーセットで使用することが可能です。インスタンスは、6つのJSONデータ型のいずれにも属さない場合があります。

この場合、アノテーションは依然として適用されますが、ほとんどの検証キーワードは役に立ちません。常にパスするか、常に失敗するためです。

カスタムボキャブラリは、コアデータモデルのスーパーセットのサポートを定義できます。「const」キーワードを使用するために、スキーマ自体は、このスーパーセットでのみ表現できる場合があります。

4.3. JSONスキーマ文書

JSONスキーマ文書、または単にスキーマとは、インスタンスを記述するために使用されるJSON文書です。スキーマ自体はインスタンスとして解釈できますが、「application/schema-instance+json」ではなく、「application/schema+json」というメディアタイプを常に指定する必要があります。「application/schema+json」メディアタイプは、「application/schema-instance+json」によって提供されるフラグメント識別子の構文とセマンティクスのスーパーセットを提供するように定義されています。

JSONスキーマは、オブジェクトまたはブール値である必要があります。

4.3.1. JSONスキーマオブジェクトとキーワード

インスタンスに適用されるオブジェクトプロパティは、キーワードまたはスキーマキーワードと呼ばれます。大まかに言って、キーワードは次の5つのカテゴリのいずれかに分類されます。

識別子
スキーマのURIを設定したり、ベースURIの決定方法を変更したりすることで、スキーマの識別を制御します
アサーション
インスタンスに適用されると、ブール値の結果を生成します
アノテーション
アプリケーションの使用のためにインスタンスに情報を添付します
アプリケータ
1つ以上のサブスキーマをインスタンス内の特定の場所に適用し、その結果を組み合わせたり変更したりします
予約済み場所
直接結果に影響を与えませんが、相互運用性を確保するために特定の目的のために場所を予約します

キーワードは複数のカテゴリに分類される場合がありますが、アプリケータは、サブスキーマの結果に基づいてアサーション結果を生成する必要があります。サブスキーマとは無関係に追加の制約を定義するべきではありません。

同じスキーマオブジェクト内のプロパティであるキーワードは、隣接キーワードと呼ばれます。

この文書とその関連文書以外で定義されている拡張キーワードは、他の動作も自由に定義できます。

JSONスキーマには、スキーマキーワードではないプロパティを含めることができます。不明なキーワードは、キーワードの値がアノテーションの値であるアノテーションとして処理する必要があります。

空のスキーマとは、プロパティがないか、不明なプロパティのみを持つJSONスキーマです。

4.3.2. ブール値JSONスキーマ

ブール値スキーマの値「true」と「false」は、インスタンス値に関係なく、常にそれ自体をアサーション結果として生成する自明なスキーマです。アノテーションの結果を生成することはありません。

これらのブール値スキーマは、スキーマ作成者の意図を明確にし、スキーマ処理の最適化を容易にするために存在します。(この文書で定義されているサブスキーマアプリケーションボキャブラリの一部である)"not"を含む、次のスキーマオブジェクトと同様に動作します。

true
空のスキーマ{}の場合と同様に、常に検証に合格します
false
スキーマ{"not": {}}の場合と同様に、常に検証に失敗します

空のスキーマオブジェクトは明確ですが、「false」スキーマには多くの可能な同等物が存在します。ブール値を使用することで、人間の読者と実装の両方に意図が明確になります。

4.3.3. スキーマボキャブラリ

スキーマボキャブラリ、または単にボキャブラリとは、キーワード、その構文、およびそのセマンティクスの集合です。ボキャブラリは一般的に特定の目的に沿って構成されています。検証、ハイパーメディア、ユーザーインターフェースの生成など、JSONスキーマのさまざまな用途には、さまざまなボキャブラリの集合が関係します。

ボキャブラリはJSONスキーマにおける再利用の主要な単位です。スキーマ作成者は、スキーマを処理するために必要なボキャブラリまたはオプションのボキャブラリを示すことができます。ボキャブラリはメタスキーマでURIによって識別されるため、一般的な実装では、以前は不明だったボキャブラリをサポートする拡張機能をロードできます。キーワードはボキャブラリの外部でサポートできますが、個々のキーワードの使用を示す同様のメカニズムはありません。

スキーマボキャブラリは、対象者と相互運用性の期待に応じて、非公式な説明から標準提案まで、何でも定義できます。特に、非公開組織内でのボキャブラリ使用を容易にするために、ボキャブラリの仕様をその使用範囲の外部に公開する必要はありません。

4.3.4. メタスキーマ

それ自体がスキーマを記述するスキーマは、メタスキーマと呼ばれます。メタスキーマは、JSONスキーマを検証し、それらが使用しているボキャブラリを指定するために使用されます。

通常、メタスキーマはボキャブラリの集合を指定し、それらのボキャブラリの構文に準拠するスキーマを検証します。ただし、メタスキーマとボキャブラリは別々であるため、メタスキーマは、ボキャブラリの仕様が求めるよりも厳密に、または緩やかにスキーマの適合性を検証できます。メタスキーマは、正式なボキャブラリの一部ではない追加のキーワードも記述および検証できます。

4.3.5. ルートスキーマとサブスキーマおよびリソース

JSONスキーマリソースとは、正規の [RFC6596]絶対URI [RFC3986]によって識別されるスキーマです。スキーマリソースは、結果として得られるセカンダリリソース(RFC 3986のセクション3.5 [RFC3986]で定義)がプライマリリソースと同一である場合、フラグメントを含むURIによって識別することもできます。これは、空のフラグメントの場合、または1つのスキーマリソースが別のスキーマリソースに埋め込まれている場合に発生する可能性があります。フラグメントを含むそのようなURIは、非正規とみなされます。

ルートスキーマとは、問題のJSON文書全体を構成するスキーマです。ルートスキーマは常にスキーマリソースであり、URIはセクション9.1.1で説明されているように決定されます。他の形式にスキーマを埋め込んだ文書には、この意味でのルートスキーマリソースがありません。そのような使用方法がJSONスキーマ文書とリソースの概念にどのように適合するかは、今後のドラフトで明確になります。

一部のキーワードはスキーマ自体を受け入れるため、JSONスキーマをネストできます。

{
    "title": "root",
    "items": {
        "title": "array item"
    }
}

この例文書では、「array item」というタイトルのスキーマはサブスキーマであり、「root」というタイトルのスキーマはルートスキーマです。

ルートスキーマと同様に、サブスキーマはオブジェクトまたはブール値のいずれかです。

セクション8.2.1で説明されているように、JSONスキーマ文書には複数のJSONスキーマリソースを含めることができます。限定せずに使用する場合、「ルートスキーマ」という用語は、文書のルートスキーマを参照します。場合によっては、リソースルートスキーマについて説明します。リソースのルートスキーマは、その最上位レベルのスキーマオブジェクトであり、リソースがスタンドアロンのJSONスキーマ文書に抽出された場合も文書ルートスキーマとなります。

複数のスキーマリソースが埋め込まれているか、参照によってリンクされているかに関係なく、同じ方法で、同じ利用可能な動作で処理されます。

5. フラグメント識別子

RFC 6839 [RFC6839]のセクション3.1に従って、任意の+jsonメディアタイプに対して指定されたフラグメント識別子の構文とセマンティクスは、「application/json」に対して指定されたものと同じである必要があります。(この文書の公開時点では、「application/json」に対して定義されたフラグメント識別子の構文はありません)。

さらに、「application/schema+json」メディアタイプは、単純な名前とJSONポインタの2つのフラグメント識別子構造をサポートしています。「application/schema-instance+json」メディアタイプは、JSONポインタの1つのフラグメント識別子構造をサポートしています。

URIフラグメント識別子としてのJSONポインタの使用については、RFC 6901 [RFC6901]で説明されています。2つのフラグメント識別子構文をサポートする「application/schema+json」の場合、空文字列を含むJSONポインタ構文に一致するフラグメント識別子は、JSONポインタフラグメント識別子として解釈する必要があります。

W3Cのフラグメント識別子のベストプラクティス [W3C.WD-fragid-best-practices-20121025]に従って、「application/schema+json」の単純な名前のフラグメント識別子は、ローカルに名前が付けられたスキーマを参照するために予約されています。JSONポインタ構文と一致しないすべてのフラグメント識別子は、単純な名前のフラグメント識別子として解釈する必要があります。

"application/schema+json" ドキュメント内でのプレーンネームフラグメント識別子の定義と参照は、"$anchor"キーワード (8.2.2節)で規定されています。

6. 一般的な考慮事項

6.1. JSON値の範囲

インスタンスは、JSON [RFC8259]で定義されている任意の有効なJSON値とすることができます。JSON Schemaは型に制限を課しません。JSON Schemaは、nullなど、任意のJSON値を記述できます。

6.2. プログラミング言語の独立性

JSON Schemaはプログラミング言語に依存せず、データモデルで記述されている値の全範囲をサポートします。ただし、一部の言語とJSONパーサーでは、JSONで記述できる値の全範囲をメモリ上に表現できない場合があります。

6.3. 数学的整数

一部のプログラミング言語とパーサーでは、浮動小数点数と整数の内部表現が異なります。

一貫性のために、整数JSON数値は小数部を含めてエンコードすべきではありません。

6.4. 正規表現

キーワードは、制約を表現するために、またはインスタンス値を正規表現に制約するために、正規表現を使用する場合があります。これらの正規表現は、ECMA-262、21.2.1節 [ecma262]で記述されている正規表現の方言に従って有効である必要があります。

正規表現は、Unicodeサポートを提供するために「u」フラグ(または同等物)を使用して構築するか、ECMA-262で定義されているようにUnicodeサポートを提供する方法で処理する必要があります。

さらに、正規表現構成要素のサポートに大きなばらつきがあることを考えると、スキーマ作成者は、次の正規表現トークンに限定する必要があります。

  • JSON仕様 [RFC8259]で定義されている個々のUnicode文字;
  • 単純な文字クラス([abc])、範囲文字クラス([a-z]);
  • 補集合文字クラス([^abc]、[^a-z]);
  • 単純な量子化子:「+」(1回以上)、「*」(0回以上)、「?」(0回または1回)、およびそれらの遅延バージョン(「+?」、「*?」、「??」);
  • 範囲量子化子:「{x}」(正確にx回)、「{x,y}」(少なくともx回、最大y回)、「{x,}」(x回以上)、およびそれらの遅延バージョン;
  • 入力の先頭アンカー(「^」)と入力の末尾アンカー(「$」);
  • 単純なグループ化(「(...)」)と選択(「|」)。

最後に、実装は、正規表現の先頭と末尾の両方にアンカーされているとみなしてはなりません。つまり、たとえば、「es」というパターンは「expression」に一致します。

6.5. JSON Schemaの拡張

追加のスキーマキーワードとスキーマボキャブラリーは、任意のエンティティによって定義できます。明示的な合意がない限り、スキーマ作成者は、そのようなサポートを明示的に文書化していない実装によって、これらの追加のキーワードとボキャブラリーがサポートされると期待してはなりません。実装は、サポートしていないキーワードをアノテーションとして扱い、キーワードの値をアノテーションの値として扱う必要があります。

実装は、直接サポートしていないボキャブラリーのハンドラーを登録またはロードする機能を提供できます。そのようなハンドラーの登録と実装の正確なメカニズムは、実装依存です。

7. キーワードの動作

JSON Schemaのキーワードは、いくつかの一般的な動作カテゴリに分類されます。アサーションは、インスタンスが制約を満たしていることを検証し、ブール値の結果を生成します。アノテーションは、アプリケーションが任意の方法で使用できる情報を添付します。アプリケーターは、サブスキーマをインスタンスの一部に適用し、その結果を組み合わせます。

拡張キーワードは、これらのカテゴリ内に留まる必要があります。特にアノテーションは非常に柔軟であることを考慮する必要があります。複雑な動作は、通常、スキーマキーワードとして直接実装するよりも、アノテーションデータに基づいてアプリケーションに委任する方が優れています。ただし、拡張キーワードは、特殊な目的のために他の動作を定義できます。

スキーマに対してインスタンスを評価するには、スキーマ内のすべてのキーワードをインスタンス内の適切な場所で処理する必要があります。通常、アプリケーターキーワードは、アプリケーター(したがってサブスキーマ)のないスキーマオブジェクトに到達するまで処理されます。インスタンス内の適切な場所は、スキーマオブジェクト内のアサーションとアノテーションキーワードに対して評価され、その結果はアプリケーターのルールに従って親スキーマに収集されます。

親スキーマオブジェクトの評価は、そのすべてのサブスキーマが評価されると完了しますが、状況によっては、アサーションの結果によって評価が短絡される場合があります。アノテーションを収集している場合、アノテーションの結果を変更できないサブスキーマも含めて、すべてサブスキーマを検査する必要があるため、一部のアサーション結果の短絡はできません。

7.1. 字句スコープと動的スコープ

JSON Schemaのほとんどのキーワードは、単独で評価できるか、多くても同じスキーマオブジェクト内の隣接するキーワードの値または結果を考慮する必要があるだけです。

キーワードの字句スコープは、オブジェクトと配列の入れ子になったJSONデータ構造によって決定されます。そのようなスコープの中で最大のものは、スキーマドキュメント全体です。最小のスコープは、サブスキーマのない単一のスキーマオブジェクトです。

キーワードは、URI参照など、部分的な値で定義できます。これは、別のURI参照や完全なURIなど、JSONドキュメントの字句構造によって見つけられる別の値に対して解決する必要があります。「$id」、「$ref」、「$dynamicRef」コアキーワード、および「base」JSONハイパー スキーマキーワードは、この種の動作の例です。

「$schema」などのキーワードは、スキーマリソース全体の字句スコープに適用されるため、スキーマリソースのルートスキーマにのみ表示される必要があります。

他のキーワードは、通常、インスタンスドキュメントとともに、スキーマの評価中に存在する動的スコープを考慮する場合があります。最外部の動的スコープは、スキーマリソースのルートではない場合でも、処理を開始するスキーマオブジェクトです。このルートスキーマから特定のキーワードへのパス(解決された可能性のある「$ref」および「$dynamicRef」キーワードを含む)は、キーワードの「検証パス」とみなされます。

参照キーワードが遭遇するまで、字句スコープと動的スコープは一致しています。参照キーワードに従うことで、処理が1つの字句スコープから別の字句スコープに移動しますが、動的スコープの観点からは、参照に従うことは、値として存在するサブスキーマに降りるのと変わりありません。動的スコープを通じて情報を解決する参照の反対側のキーワードは、ローカルに字句的に囲んでいる親ではなく、参照の元の側を動的な親とみなします。

動的スコープの概念は、主に「$dynamicRef」と「$dynamicAnchor」で使用され、高度な機能とみなされ、追加のキーワードを定義する際には注意して使用する必要があります。エラーと収集されたアノテーションを報告する場合にも表示されます。これは、同じ字句スコープを異なる動的スコープで繰り返し再訪できる可能性があるためです。そのような場合、ユーザーにエラーまたはアノテーションを生成した動的パスを通知することが重要です。

7.2. キーワードの相互作用

キーワードの動作は、サブスキーマ (4.3.5節)および/または隣接するキーワード(同じスキーマオブジェクト内のキーワード)とそのサブスキーマのアノテーション結果に基づいて定義できます。そのようなキーワードは、循環依存につながってはなりません。キーワードは、同じスキーマオブジェクト (4.3節)内の別のキーワードの存在または非存在に基づいて動作を変更できます。

7.3. デフォルトの動作

欠落しているキーワードは、偽のアサーション結果を生成してはならず、アノテーション結果を生成してはならず、独自の動作定義の一部として他のスキーマの評価を引き起こしてはなりません。ただし、欠落しているキーワードはアノテーションに寄与しないため、アノテーション結果の不足は、間接的に他のキーワードの動作を変更する可能性があります。

場合によっては、欠落しているキーワードのアサーション動作は、特定の値によって生成される動作と同一であり、キーワードの定義では、既知のそのような値を注意する必要があります。ただし、デフォルトの動作を生成する値が、存在する場合にアノテーション結果を生成する場合でも、デフォルトの動作はアノテーションを生成してはなりません。

アノテーションの収集は、計算とメモリの両方の点で大きなコストを追加するため、実装はこれを省略できます。収集されたアノテーションの観点から指定されているキーワードは、適切な場合は妥当な代替アプローチを説明する必要があります。このアプローチは、このドキュメントの「items」と「additionalProperties」キーワードによって示されています。

そのような代替アプローチがキーワードに対して不可能な場合、アノテーションの収集をサポートしていない実装は、それらのキーワードまたはそれらを含むボキャブラリーをサポートできなくなることに注意してください。

7.4. 識別子

識別子は、スキーマのURIを定義するか、参照 (8.2.3節)におけるそのようなURIの解決方法、またはその両方に影響を与えます。このドキュメントで定義されているコアボキャブラリーは、特に「$id」など、いくつかの識別キーワードを定義しています。

標準的なスキーマURIは、インスタンスの処理中に変更してはなりませんが、URI参照の解決に影響を与えるキーワードは、実行時にのみ完全に決定される動作を持つ場合があります。

カスタム識別子キーワードは可能ですが、ボキャブラリー設計者は、コアキーワードの機能を妨げないように注意する必要があります。たとえば、この仕様の「$dynamicAnchor」キーワードは、そのURI解決効果を一致する「$dynamicRef」キーワードに制限し、「$ref」の動作を妨げません。

7.5. アプリケーター

適用者は、単一のスキーマオブジェクトでは実現できないよりも複雑なスキーマの構築を可能にします。インスタンスに対するスキーマ文書 (セクション 4.3) の評価は、ルートスキーマ (セクション 4.3.5) を完全なインスタンス文書に適用することから始まります。そこから、適用者と呼ばれるキーワードを使用して、適用される追加のスキーマを決定します。そのようなスキーマは、現在の場所に、または子場所にインプレースで適用される場合があります。

適用されるスキーマは、キーワードの値の一部または全部を構成するサブスキーマとして存在する場合があります。あるいは、適用者は、同じスキーマ文書内の他の場所、または別のスキーマ文書内のスキーマを参照する場合もあります。そのような参照されるスキーマを識別するメカニズムは、キーワードによって定義されます。

適用者キーワードは、サブスキーマまたは参照されたスキーマのブール値アサーション (セクション 7.6)の結果がどのように変更および/または結合されて適用者のブール値の結果を生成するかを定義します。適用者は、サブスキーマのアサーション結果に任意のブール論理演算を適用できますが、独自のアサーション条件を新たに導入することはしてはいけません

アノテーション (セクション 7.7) の結果は、インスタンスの位置とスキーマキーワードの位置とともに保持されるため、アプリケーションは複数の値をどのように解釈するかを決定できます。

7.5.1. 参照スキーマと参照元スキーマ

セクション 7.5で述べたように、適用者キーワードは、適用するスキーマを含めるのではなく、適用者値にサブスキーマとして含めることができます。このような状況では、適用されるスキーマは参照スキーマと呼ばれ、適用者キーワードを含むスキーマは参照元スキーマと呼ばれます。

ルートスキーマとサブスキーマは、スキーマ文書内でのスキーマの位置に基づく静的な概念であるのに対し、参照スキーマと参照元スキーマは動的です。スキーマに対するインスタンスの評価中に、さまざまなスキーマのペアがさまざまな参照スキーマと参照元スキーマの配置になる可能性があります。

"$ref" (セクション 8.2.3.1)などの、参照による一部の適用者では、参照スキーマはスキーマ文書の字句スコープの静的分析によって決定できます。 "$dynamicRef"("$dynamicAnchor"付き)など、他の適用者は動的スコープを使用するため、インスタンスを使用してスキーマを評価するプロセスでのみ解決できます。

7.6. アサーション

JSON スキーマは、JSON ドキュメントに対する制約をアサートするために使用でき、アサーションに合格または不合格になります。このアプローチは、制約への適合性を検証したり、制約を満たすために必要なものを文書化したりするために使用できます。

JSON スキーマの実装は、インスタンスをスキーマのアサーションに対して評価するときに、単一のブール値の結果を生成します。

インスタンスは、スキーマに存在するアサーションにのみ不合格になる可能性があります。

7.6.1. アサーションとインスタンスのプリミティブ型

ほとんどのアサーションは、特定のプリミティブ型内の値のみを制約します。インスタンスの型がキーワードの対象となる型でない場合、インスタンスはアサーションに準拠していると見なされます。

たとえば、付属の検証ボキャブラリ [json-schema-validation]の"maxLength"キーワードは、特定の文字列(長すぎる文字列)のみを無効にするように制限します。インスタンスが数値、ブール値、null、配列、またはオブジェクトの場合、このアサーションに対して有効です。

この動作により、複数のプリミティブ型である可能性のあるインスタンスでキーワードをより簡単に使用できます。付属の検証ボキャブラリには、「type」キーワードも含まれており、インスタンスを1つ以上のプリミティブ型に独立して制限できます。これにより、特定の長さの文字列またはnull値のいずれかを返す可能性のある関数などのユースケースを簡潔に表現できます。

{
    "type": ["string", "null"],
    "maxLength": 255
}

"maxLength"がインスタンスの型を文字列に制限した場合、例のように記述するとnull値が実際には許可されなくなるため、表現が大幅に複雑になります。明示的に指定されていない限り、各キーワードは個別に評価されるため、「maxLength」がインスタンスを文字列に制限した場合、「type」に「null」を含めても有用な効果はありません。

7.7. アノテーション

JSON スキーマは、インスタンスがアノテーションを含むスキーマオブジェクトとそのすべての親スキーマオブジェクトに対して検証されるたびに、インスタンスに情報をアノテーションできます。情報は単純な値でも、インスタンスの内容に基づいて計算された値でもかまいません。

アノテーションは、インスタンス内の特定の場所に添付されます。多くのサブスキーマを単一の場所に適用できるため、アプリケーションは、異なるスキーマオブジェクト内の同じスキーマキーワードによって同じインスタンスの場所に添付された異なるアノテーション値をどのように処理するかを決定する必要がある場合があります。

アサーションの結果とは異なり、アノテーションデータはさまざまな形式を取ることができ、アプリケーションが自由に使用できます。JSON スキーマの実装は、アプリケーションに代わって収集された情報を使用することは想定されていません。

特に指定がない限り、アノテーションキーワードの値はキーワードの値です。ただし、他の動作も可能です。たとえば、JSON ハイパーシェーマ [json-hyper-schema]の"links"キーワードは、インスタンスデータの一部に基づいて値を生成する複雑なアノテーションです。

アサーションでは「ショートサーキット」評価が可能ですが、アノテーションを収集するには、全体のアサーション結果を変更できない場合でも、インスタンスの場所に適用されるすべてのスキーマを調べる必要があります。唯一の例外は、検証に失敗したスキーマオブジェクトのサブスキーマはスキップできることです(失敗したスキーマのアノテーションは保持されません)。

7.7.1. アノテーションの収集

アノテーションは、アノテーション収集動作を明示的に定義するキーワードによって収集されます。ブール値のスキーマはキーワードを使用しないため、アノテーションを生成できないことに注意してください。

収集されたアノテーションには、次の情報を含める必要があります

  • アノテーションを生成するキーワードの名前
  • 添付先のインスタンスの位置(JSON ポインタとして)
  • "$ref"などの参照キーワードに従って絶対スキーマの位置に到達する方法を示すスキーマの位置パス
  • 添付キーワードの絶対スキーマの位置(URI として)。上記のスキーマの位置パスと同じ場合は、省略できます。
  • 添付された値
7.7.1.1. 複数の値の区別

アプリケーションは、値に寄与したスキーマの位置に基づいて、複数のアノテーション値のどれを使用するかを決定できます。これは、柔軟な使用を許可することを目的としています。スキーマの位置を収集することで、そのような使用が容易になります。

たとえば、検証仕様 [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
        }
    }
}

この例では、機能 A と機能 B の両方で、再利用可能な「enabledToggle」スキーマを使用しています。そのスキーマは、「title」、「description」、「default」のアノテーションを使用します。したがって、アプリケーションは、機能 A の追加の「default」値と、機能 B の追加の「description」値をどのように処理するかを決定する必要があります。

アプリケーションプログラマとスキーマ作成者は、使用方法で合意する必要があります。この例では、最も具体的な「default」値が使用され、追加の、より一般的な「default」値は無視されると仮定します。また、すべての「description」テキストが使用され、最も一般的なものから始まり、最も具体的なもので終わると仮定します。これには、スキーマ作成者がこのように結合して機能する説明を作成する必要があります。

アプリケーションは、スキーマの位置パスを使用して、どの値がどの値であるかを判断できます。「enabled」プロパティスキーマのすぐ下の値はより具体的であり、「$ref」で参照される再利用可能なスキーマの下の値はより一般的です。スキーマの位置パスは、各値が「$ref」を横断して見つかったかどうかを示します。

したがって、機能 A はtrueのデフォルト値を使用し、機能 B はnullの一般的なデフォルト値を使用します。機能 A には「enabledToggle」スキーマからの一般的な説明のみが含まれ、機能 B はその説明を使用して、null値の解釈方法を説明するローカルに定義された説明も追加します。

異なるアプリケーションが採用する可能性のある他の妥当なアプローチがあることに注意してください。たとえば、アプリケーションは、「default」の2つの異なる値が存在することを、スキーマの位置に関係なくエラーと見なす場合があります。

7.7.1.2. アノテーションとアサーション

falseのアサーション結果を生成するスキーマオブジェクトは、独自キーワードまたはサブスキーマ内のキーワードからのアノテーション結果を生成してはなりません

全体的なスキーマの結果には、他のスキーマの位置から収集されたアノテーションが含まれる場合があることに注意してください。このスキーマを考慮してください。

{
    "oneOf": [
        {
            "title": "Integer Value",
            "type": "integer"
        },
        {
            "title": "String Value",
            "type": "string"
        }
    ]
}

インスタンス「This is a string」に対して、そのスキーマオブジェクト内の型のアサーションが失敗するため、「Integer Value」というタイトルのアノテーションは破棄されます。インスタンスは文字列型のアサーションに合格するため、「String Value」というタイトルのアノテーションは保持されます。

7.7.1.3. アノテーションと適用者

適用者キーワードは、独自の注釈結果を定義する可能性に加えて、サブスキーマまたは参照されたスキーマで収集された注釈を集約します。

7.8. 予約済み場所

4番目のキーワードのカテゴリは、スキーマ作成者にとって有用な再利用可能なコンポーネントやデータを保持するための場所を予約するだけで、再利用には適していません。これらのキーワードは、検証やアノテーションの結果に影響を与えません。コアボキャブラリにおけるそれらの目的は、特定の用途のために場所が利用可能であり、拡張キーワードによって再定義されないことを保証することです。

これらのキーワードは、9.4.2項で説明されているように、結果に直接影響を与えることはありませんが、再利用可能なスキーマの場所を予約する認識されない拡張キーワードは、特定の状況下で参照との望ましくない相互作用を引き起こす可能性があります。

7.9. インスタンスデータの読み込み

この文書または関連文書の一部として定義されているボキャブラリは、インスタンスデータをターゲットおよび/または読み込む可能性のあるキーワードを定義していませんが、他のボキャブラリがそうしたい可能性があります。

キーワードは、JSONポインタまたは相対JSONポインタを使用して、現在の評価場所外のインスタンスの一部を検査するように定義できます。

相対JSONポインタを使用して場所の調整を許可するキーワードは、デフォルトが望ましい場合は、現在の場所を使用する必要があります。

8. JSONスキーマコアボキャブラリ

このセクションで宣言されているキーワード(すべて「$」で始まる)は、JSONスキーマコアボキャブラリを構成します。これらのキーワードは、複数の文書に分割されているものも含め、すべてのスキーマまたはメタスキーマを処理するために必要であるか、または保証された相互運用性を必要とする目的のためにキーワードを予約するために存在します。

コアボキャブラリは、以降のボキャブラリの処理をブートストラップするために、常に必須と見なす必要があります。使用中のボキャブラリを宣言するために"$vocabulary" (8.1項)キーワードを使用するメタスキーマは、必須であることを示すtrueの値を持つコアボキャブラリを明示的にリストする必要があります。

このボキャブラリ(そしてこのボキャブラリのみ)のfalse値の動作は未定義であり、「$vocabulary」が存在するがコアボキャブラリが含まれていない場合の動作も未定義です。ただし、実装ではこれらのケースを検出して発生時にエラーを発生させることを推奨します。メタスキーマがコアをオプションで使用することを宣言することは意味がありません。

「$vocabulary」を使用しないメタスキーマは、そのURIがtrueの値で存在する場合と同様に、コアボキャブラリを必要とするものと見なす必要があります。

コアボキャブラリの現在のURIは次のとおりです。<https://json-schema.dokyumento.jp/draft/2020-12/vocab/core>。

対応するメタスキーマの現在のURIは次のとおりです。https://json-schema.dokyumento.jp/draft/2020-12/meta/core

「$」プレフィックスはコアボキャブラリのために正式に予約されていませんが、将来の衝突を回避するために、拡張キーワード(ボキャブラリ内またはそれ以外)は「$」以外の文字で始めることを推奨します。

8.1. メタスキーマとボキャブラリ

メタスキーマとボキャブラリの2つの概念は、実装がスキーマをどのように解釈するかを知らせるために使用されます。すべてのスキーマにはメタスキーマがあり、「$schema」キーワードを使用して宣言できます。

メタスキーマは2つの目的を果たします。

使用中のボキャブラリの宣言
メタスキーマに表示される「$vocabulary」キーワードは、そのメタスキーマを参照するスキーマで使用できるボキャブラリを宣言します。ボキャブラリは、キーワードのセマンティクスと、その一般的な構文を定義します。
有効なスキーマ構文の説明
スキーマは、使用可能なキーワードの構文を制約するメタスキーマに対して正常に検証する必要があります。説明されている構文は、宣言されたボキャブラリと互換性があると予想されます。非互換な構文を記述することは可能ですが、そのようなメタスキーマは役に立たない可能性が高いです。

メタスキーマはボキャブラリとは別に、ボキャブラリをさまざまな方法で組み合わせたり、メタスキーマの作成者が、開発およびテストサイクルで行われる可能性のある、特定のキーワードの禁止や、通常よりも厳格な構文検証の実行など、追加の制約を課したりできるようにするためです。各ボキャブラリは通常、ボキャブラリのキーワードのみで構成されるメタスキーマを識別します。

メタスキーマの作成は、JSONスキーマの高度な使用方法であるため、メタスキーマ機能の設計では、シンプルさよりも柔軟性が重視されています。

8.1.1. "$schema"キーワード

"$schema"キーワードは、JSONスキーマの方言識別子として、そしてそれ自体がJSONスキーマであるリソースの識別子として使用され、この特定の方言に対して記述された有効なスキーマのセットを記述します。

このキーワードの値はURI [RFC3986](スキームを含む)でなければならず、このURIは正規化されている必要があります。現在のスキーマは、このURIによって識別されるメタスキーマに対して有効である必要があります。

このURIが取得可能なリソースを識別する場合、そのリソースはメディアタイプ「application/schema+json」である必要があります。

"$schema"キーワードは、ドキュメントルートスキーマオブジェクトで使用される必要があり、埋め込まれたスキーマリソースのルートスキーマオブジェクトで使用される場合があります。リソース以外のルートスキーマオブジェクトには表示できません。ドキュメントルートスキーマに存在しない場合、その結果の動作は実装によって定義されます。

このプロパティの値は、この文書および他の文書、および他の当事者によって定義されています。

8.1.2. "$vocabulary"キーワード

"$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'に対して検証できます。

8.1.2.1. デフォルトのボキャブラリ

"$vocabulary"がない場合、実装は、参照しているスキーマの"$schema"キーワードのURI値から認識される場合、メタスキーマに基づいて動作を決定できます。これは、ボキャブラリが存在する前に、ハイパーシースマの使用などの動作が認識されていた方法です。

スキーマによって参照されるメタスキーマが認識されない場合、または存在しない場合、動作は実装によって定義されます。実装がスキーマの処理を続行する場合、コアボキャブラリの使用を想定する必要があります。実装が特定の目的のために構築されている場合、その目的のために最も関連性の高いすべてのボキャブラリの使用を想定する必要があります。

たとえば、バリデータである実装は、この仕様と関連する検証仕様内のすべてのボキャブラリの使用を想定する必要があります。

8.1.2.2. ボキャブラリの非継承性

"$vocabulary"に関する処理の制限により、"$ref"または同様のキーワードを使用して他のメタスキーマを参照するメタスキーマは、それらの他のメタスキーマのボキャブラリの宣言を自動的に継承しません。そのような宣言はすべて、メタスキーマとして使用されることを目的とした各スキーマドキュメントのルートに繰り返す必要があります。これは、メタスキーマの例 (付録D.2)で示されています。 この要件により、実装は各メタスキーマの単一箇所ですべてのボキャブラリの要件情報を検出できます。スキーマの拡張可能性は、参照によってより細かいメタスキーマを組み合わせる可能性のある無数の方法があることを意味するため、実装にすべての可能性を予測させ、参照されるメタスキーマ内のボキャブラリを検索させることは、非常に負担が大きくなります。

8.1.3. メタスキーマとボキャブラリのURIの更新

エラーを修正するために、仕様ドラフト間で更新されたボキャブラリとメタスキーマのURIを公開できます。実装は、この仕様ドラフトの後で次のドラフトの前に日付が付けられたURIを、ここに記載されているものと同じ構文とセマンティクスを示すものと見なす必要があります。

8.2. ベースURI、アンカー、および逆参照

広大なエコシステム内のスキーマを区別するために、スキーマはURI [RFC3986]によって識別され、それらのURIを指定することで他のスキーマへの参照を埋め込むことができます。

いくつかのキーワードは、相対的なURI参照 [RFC3986]、または相対URI参照を作成するために使用される値を受け入れることができます。これらのキーワードでは、参照を解決するためにベースURIを確立する必要があります。

8.2.1. "$id"キーワード

"$id"キーワードは、その標準 [RFC6596] URIでスキーマリソースを識別します。

このURIは識別子であり、必ずしもネットワークロケータではないことに注意してください。ネットワークアドレス指定可能なURLの場合、スキーマはその標準URIからダウンロード可能である必要はありません。

存在する場合、このキーワードの値は文字列でなければならず、有効なURI参照 [RFC3986]を表す必要があります。このURI参照は正規化されるべきであり、絶対URI [RFC3986](フラグメントなし)またはフラグメントが空のURIに解決されなければなりません。

空のフラグメント形式は推奨されず、後方互換性のため、およびapplication/schema+jsonメディアタイプが空のフラグメントを持つURIはフラグメントを削除した同じURIと同じリソースを識別すると定義しているため、保持されています。しかし、この等価性はRFC 3986の正規化プロセス [RFC3986]の一部ではないため、実装者とスキーマ作成者は、一般的なURIライブラリがこれを理解できるとは想定できません。

したがって、「$id」は空でないフラグメントを含んではならず、空のフラグメントを含めるべきではありません。絶対URI形式は、空のフラグメントの有無に関わらず、標準URIとみなされなければなりません。 空のフラグメントは現在許可されていますが、これは古いメタスキーマがその$id(または以前はid)に空のフラグメントを持っているためです。将来のドラフトでは、「$id」内の空のフラグメントさえも完全に禁止される可能性があります。

絶対URIは、スキーマリソース内のキーワードにおける相対URI参照の基本URIとしても機能します。RFC 3986セクション5.1.1 [RFC3986]で、コンテンツに埋め込まれた基本URIについて説明されています。

サブスキーマに「$id」が存在することは、サブスキーマが単一のスキーマドキュメント内に別個のスキーマリソースを構成することを示しています。さらに、RFC 3986セクション5.1.2 [RFC3986]でエンティティのカプセル化について説明されているように、サブスキーマの「$id」が相対URI参照である場合、その参照を解決するための基本URIは親スキーマリソースのURIです。

親スキーマオブジェクトが「$id」を使用してリソースとして明示的に識別されていない場合、基本URIは前のセクション (セクション9.1.1)で示された手順で確立されたドキュメント全体のURIです。

8.2.1.1. ルートスキーマの識別

JSONスキーマドキュメントのルートスキーマには、絶対URI [RFC3986](スキームを含むがフラグメントを含まない)を持つ「$id」キーワードが含まれている必要があります。

8.2.2. 場所によらない識別子の定義

JSONポインタフラグメントを使用するには、スキーマの構造に関する知識が必要です。再利用可能なスキーマを提供することを意図してスキーマドキュメントを作成する場合は、特定の構造上の場所には依存しないプレーンな名前フラグメントを使用する方が適切です。これにより、JSONポインタ参照を更新せずにサブスキーマを再配置できます。

「$anchor」と「$dynamicAnchor」キーワードは、そのようなフラグメントを指定するために使用されます。「$id」のように絶対URIを作成するためではなく、プレーンな名前フラグメントを作成するためにのみ使用できる識別子キーワードです。

結果のフラグメントが追加される基本URIは、「$anchor」または「$dynamicAnchor」を含むスキーマリソースの標準URIです。前のセクションで説明したように、これは同じスキーマオブジェクトまたは親スキーマオブジェクト内の最も近い「$id」、またはRFC 3986に従って決定されたドキュメントの基本URIのいずれかです。

URIの通常の使用方法とは別に、「$dynamicAnchor」は、「$dynamicRef」キーワードで使用される場合、フラグメントが拡張ポイントであることを示します。この低レベルの高度な機能により、メタスキーマなどの再帰的なスキーマを拡張することが容易になり、その拡張に特定のセマンティクスを課す必要がありません。"$dynamicRef" (セクション8.2.3.2)のセクションを参照してください。

ほとんどの場合、通常のフラグメントの動作は十分であり、より直感的です。したがって、「$dynamicAnchor」の明確な必要がない限り、「$anchor」を使用してプレーンな名前フラグメントを作成することを推奨します。

存在する場合、このキーワードの値は文字列でなければならず、文字([A-Za-z])またはアンダースコア("_")で始まり、その後、任意の数の文字、数字([0-9])、ハイフン("-")、アンダースコア("_")、ピリオド(".")が続きます。これは、XMLのNCName生成 [xml-names]のUS-ASCII部分と一致します。 アンカー文字列には「#」文字が含まれていないことに注意してください。これはURI参照ではないためです。「$anchor": "foo"は、URIで使用されると「#foo」というフラグメントになります。完全な例については以下を参照してください。

「$anchor」および/または「$dynamicAnchor」の任意の組み合わせを使用して、同じリソース内で同じフラグメント名を複数回指定した場合の影響は未定義です。実装では、このような使用が検出された場合、エラーを発生させる場合があります。

8.2.3. スキーマ参照

いくつかのキーワードを使用して、現在のインスタンスの場所に適用されるスキーマを参照できます。「$ref」と「$dynamicRef」は適用子キーワードであり、参照されたスキーマをインスタンスに適用します。

「$ref」と「$dynamicRef」の値はURI参照であるため、複数のファイルにスキーマを外部化または分割し、自己参照を通じて再帰的な構造を検証する機能を提供できます。

これらのキーワードによって生成される解決済みURIは、必ずしもネットワークロケータではなく、識別子です。ネットワークアドレス指定可能なURLの場合、スキーマをアドレスからダウンロードする必要はなく、実装では、ネットワークアドレス指定可能なURIに遭遇した場合にネットワーク操作を実行すべきではないと想定するべきではありません。

8.2.3.1. 「$ref」による直接参照

「$ref」キーワードは、静的に識別されたスキーマを参照するために使用される適用子です。その結果は、参照されたスキーマの結果です。 この結果の決定方法の定義は、他のキーワードが同じスキーマオブジェクト内で「$ref」とともに表示される可能性があることを意味します。

「$ref」キーワードの値は、URI参照である文字列でなければなりません。現在のURIベースに対して解決されると、適用するスキーマのURIが生成されます。インスタンスの評価プロセスでは参照の解決方法が変更されないため、この解決はスキーマのロード時に安全に実行できます。

8.2.3.2. 「$dynamicRef」による動的参照

「$dynamicRef」キーワードは、インスタンスの評価中に遭遇するたびに、実行時まで完全な解決を遅延させることができる適用子です。

「$dynamicAnchor」と組み合わせて、「$dynamicRef」は、主に再帰的なスキーマ(自身を参照するスキーマ)で役立つ協調的な拡張メカニズムを実装します。拡張ポイントと実行時に決定される拡張ターゲットの両方が「$dynamicAnchor」で定義され、「$dynamicRef」で参照された場合にのみ、実行時の動的な動作を示します。

「$dynamicRef」プロパティの値は、URI参照である文字列でなければなりません。現在のURIベースに対して解決されると、実行時解決の開始点として使用されるURIが生成されます。この最初の解決は、スキーマのロード時に安全に実行できます。

最初に解決された開始点URIに「$dynamicAnchor」キーワードによって作成されたフラグメントが含まれている場合、最初のURIは、「$dynamicAnchor」で同じ名前のフラグメントを定義する動的スコープ (セクション7.1)内の最外部スキーマリソースのURI(フラグメントを含む)に置き換えられなければなりません。

それ以外の場合は、その動作は「$ref」と同じであり、実行時の解決は必要ありません。

これらのキーワードを使用した完全な例については、付録Cを参照してください。 2019年以前のドラフトのハイパー スキーマ メタ スキーマとこのドラフトの違いは、これらのキーワードの有用性を劇的に示しています。

8.2.4. 「$defs」によるスキーマの再利用

「$defs」キーワードは、スキーマ作成者が再利用可能なJSONスキーマをより一般的なスキーマにインラインで埋め込むための場所を予約します。このキーワードは、検証結果に直接影響を与えません。

このキーワードの値はオブジェクトでなければなりません。このオブジェクトの各メンバ値は、有効なJSONスキーマでなければなりません。

例として、正の整数制約が「$defs」内のサブスキーマである、正の整数の配列を記述するスキーマを以下に示します。

{
    "type": "array",
    "items": { "$ref": "#/$defs/positiveInteger" },
    "$defs": {
        "positiveInteger": {
            "type": "integer",
            "exclusiveMinimum": 0
        }
    }
}

8.3. 「$comment」によるコメント

このキーワードは、スキーマ作成者からスキーマの読者または保守者へのコメントのための場所を予約します。

このキーワードの値は文字列でなければなりません。実装では、この文字列をエンドユーザーに提示してはなりません。スキーマを編集するためのツールは、このキーワードの表示と編集をサポートする必要があります。このキーワードの値は、スキーマを使用する開発者を対象としたデバッグまたはエラー出力で使用できます。

スキーマボキャブラリは、ボキャブラリキーワードを含むオブジェクト内に「$comment」を許可する必要があります。実装では、ボキャブラリがそれを具体的に禁止しない限り、「$comment」が許可されていると想定できます。ボキャブラリは、この仕様で説明されているもの以外に、「$comment」の効果を指定してはなりません。

他のメディアタイプまたはプログラミング言語をapplication/schema+jsonとの間で変換するツールは、そのメディアタイプまたはプログラミング言語のネイティブコメントを"$comment"値との間で変換することを選択してもよい。ネイティブコメントと"$comment"プロパティの両方が存在する場合のそのような変換の動作は、実装依存である。

実装は、処理中の任意の時点で"$comment"値を削除してもよい。特に、これは、展開されたスキーマのサイズが問題となる場合に、スキーマを短縮することを可能にする。

実装は、"$comment"プロパティの存在、非存在、または内容に基づいて、他のいかなるアクションも実行してはならない。特に、"$comment"の値は、アノテーション結果として収集してはならない。

9. スキーマの読み込みと処理

9.1. スキーマの読み込み

9.1.1. 初期ベースURI

RFC3986 セクション 5.1 [RFC3986]は、ドキュメントのデフォルトのベースURIを決定する方法を定義している。

参考までに、スキーマの初期ベースURIは、それが検出されたURIであり、それがネットワーク上の場所、ローカルファイルシステム、または既知のスキーマのいずれかのURIによって識別可能なその他の状況であるかどうかは問わない。

スキーマドキュメントが"$id"で明示的なベースURI(コンテンツに埋め込まれている)を定義していない場合、ベースURIはRFC 3986 セクション 5 [RFC3986]に従って決定される。

ソースが不明な場合、またはソースのURIスキームが不明な場合、RFC 3986 セクション 5.1.4 [RFC3986]に記載されているように、適切な実装固有のデフォルトURIを使用してもよい。実装は、想定するデフォルトのベースURIを文書化することを推奨する。

スキーマオブジェクトが別のメディアタイプのドキュメントに埋め込まれている場合、初期ベースURIはそのメディアタイプのルールに従って決定される。

前のセクションで説明されている"$id"キーワードがルートスキーマに存在しない限り、このベースURIは、スキーマドキュメントのルートスキーマリソースの標準URIとみなされるべきである。

9.1.2. 参照されたスキーマの読み込み

リモートスキーマを識別するためにURIを使用することは、必ずしも何かがダウンロードされることを意味するものではないが、JSONスキーマの実装は、事前に使用するスキーマと、それらを識別するURIを理解する必要がある。

例えば、実行時にどのスキーマをダウンロードするかがわからない一般的なユーザーエージェントによってスキーマがダウンロードされる場合については、ハイパーメディアの使用方法 (セクション 9.5.1)を参照。

実装は、検証者がスキーマをどの程度信頼しているかに応じて、任意のURIを任意のスキーマに関連付けたり、スキーマの"$id"で指定されたURIを自動的に関連付けたりできる必要がある。そのようなURIとスキーマは、インスタンスを処理する前に実装に提供することも、処理中にスキーマドキュメント内に記述することもでき、付録Aに示すように関連付けを作成する。

スキーマは複数のURIを持つことができる(そしておそらく持つだろう)が、1つのURIが複数のスキーマを識別することはできない。複数のスキーマが同じURIとして識別しようとすると、検証者はエラー状態を発生させる必要がある。

9.1.3. メタスキーマの検出

実装は、別のスキーマの"$schema"キーワードによってメタスキーマとして識別されたために検査されている場合、スキーマをメタスキーマとして認識する必要がある。これは、単一のスキーマドキュメントが、場合によっては通常のスキーマと見なされ、他の場合はメタスキーマと見なされる可能性があることを意味する。

独自のメタスキーマであるスキーマを検査する場合、実装が通常のスキーマとして処理を開始すると、そのルールに従って処理される。しかし、独自の"$schema"値をチェックした結果、2回目に読み込まれると、メタスキーマとして扱われる。したがって、同じドキュメントは、1つのセッションの過程で両方の方法で処理される。

実装は、実装固有の目的(例えば、一般的に使用されるメタスキーマを事前に読み込み、その語彙サポート要件を事前にチェックするなど)のために、スキーマを明示的にメタスキーマとして渡すことを許可してもよい。メタスキーマの作成者は、そのような機能が実装間で相互運用可能であることを期待してはならない。

9.2. 逆参照

スキーマは、JSONポインタまたは"$id"によって直接与えられたURIを含む、与えられた任意のURIによって識別できる。いずれの場合も、「$ref」参照の逆参照には、まずその値をRFC 3986 [RFC3986]に従って現在のベースURIに対するURI参照として解決することが含まれる。

結果として得られる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>スキーマを検出すると、現在のベースURIに対して"$anchor"値をフラグメント名として解決して<https://example.net/root.json#item>を形成する。

次に、実装が<#/items>スキーマ内を見ると、<#item>参照が検出され、これが<https://example.net/root.json#item>に解決され、これは同じドキュメント内で定義されていることがわかっているので、自動的に使用できる。

"other.json"への参照を検出すると、これは<https://example.net/other.json>に解決されるが、これはこのドキュメントでは定義されていない。その識別子を持つスキーマが実装に別途提供されている場合、それも自動的に使用できる。 実装は、参照されたスキーマが不明な場合、どうすればよいのでしょうか?自動ネットワーク逆参照が許可される状況はありますか?同一オリジンポリシーは?ユーザー構成可能なオプションは?ハイパーメディアで記述された進化するAPIの場合、新しいスキーマは動的にシステムに追加されることが予想されるため、スキーマドキュメントを事前に読み込むことを絶対的に要求することは実行可能ではありません。

9.2.1. JSONポインタフラグメントと埋め込みスキーマリソース

JSONポインタURIフラグメントはスキーマドキュメントの構造に基づいて構築されるため、埋め込みスキーマリソースとそのサブスキーマは、独自の標準URI、または包含リソースのURIのいずれかに対するJSONポインタフラグメントによって識別できる。

概念的には、リンクされたスキーマリソースのセットは、各リソースがスキーマ参照 (セクション 8.2.3)で接続された個別のドキュメントであるか、または1つ以上のスキーマリソースがサブスキーマとして埋め込まれた単一ドキュメントとして構造化されているかにかかわらず、同じように動作する必要がある。

親スキーマリソースのURIに対するJSONポインタフラグメントを含む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ポインタフラグメントを使用した「https://example.com/bar#/additionalProperties」は有効なままですが、「foo」スキーマリソースの標準URIに追加されたJSONポインタフラグメントに依存していた「https://example.com/foo#/items/additionalProperties」は、もはや何も解決されません。

また、「https://example.com/foo#/items」は両方の配置で有効ですが、異なる値に解決されることにも注意してください。このURIは、リソースの取得URIと同様に機能するようになります。このURIは有効ですが、2番目の(埋め込みではない)配置で"$ref"を含むオブジェクトを特定することを特に目的としていない限り、埋め込みまたは参照されたリソースの"$id"を使用する方が堅牢です。

実装は、リソースの標準URI以外のベースと、そのベースに対するJSONポインタフラグメントを使用したURIによるスキーマ・リソースの内容へのアドレス指定をサポートしないことを選択してもよい。したがって、スキーマの作成者は、そのようなURIに依存してはならない。それらを使用すると、相互運用性が低下する可能性がある。 これは、スキーマ・リソースが再構成された場合、1つを除くすべてが脆弱になることを考えると、実装が可能なベースURIとJSONポインタフラグメントのスタック全体を追跡する必要性を回避するためです。簡単であるため禁止する必要はないと主張する人もいれば、スキーマの識別を複雑にするため禁止する必要があると主張する人もいます。このトピックに関するフィードバックを歓迎します。いくつかの議論の後、スキーマ・リソースの境界を越えて参照するJSONポインタについて、未定義、あるいは禁止された動作として話すことに「標準」の使用を取り除く必要があると感じています。(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を参照。

9.3. 複合ドキュメント

複合スキーマドキュメントは、複数の埋め込みJSONスキーマリソースを同じドキュメントにバンドルして輸送を容易にするJSONドキュメント(「バンドルされた」スキーマと呼ばれることもある)として定義される。

各埋め込みスキーマリソースは、語彙サポートの決定を含む、標準的なスキーマの読み込みと処理の要件に従って、個々のスキーマリソースとして処理する必要がある。

9.3.1. バンドル

複合スキーマドキュメントを作成するためのバンドルプロセスは、外部スキーマリソースへの参照("$ref"など)を取り、参照されたスキーマリソースを参照ドキュメント内に埋め込むこととして定義される。バンドルは、ベースドキュメントと参照/埋め込みドキュメントのすべてのURI(参照に使用される)を変更する必要がないように行う必要がある。

埋め込まれたJSONスキーマリソースはそれぞれ、スキーマ・リソースのルートにおいて"$id"キーワードを用いてURIで自身を識別し**なければならない** (MUST)。また、使用している方言を識別するために"$schema"キーワードを使用することを**推奨する** (SHOULD)。"$id"のURI識別子の値は絶対URIであることを**推奨する** (RECOMMENDED)。

参照による適用子が参照するスキーマ・リソースがバンドルされている場合、そのスキーマ・リソースは、包含するスキーマのルートにある"$defs"オブジェクトの値として配置することを**推奨する** (RECOMMENDED)。バンドルされたスキーマ・リソースの"$defs"のキーは、バンドルされたスキーマの"$id"またはアプリケーションで定義されたその他の固有の識別子(UUIDなど)であってもよい (MAY)。このキーはJSONスキーマ内で参照することを意図したものではないが、アプリケーションがバンドル処理を支援するために使用できる。

スキーマ・リソースは、その場所がスキーマの値として定義されている場合、"$defs"以外の場所に埋め込むことができる (MAY)。

バンドルされたスキーマ・リソースは、参照元のスキーマオブジェクトを置き換えたり、スキーマ・リソースを他の適用子キーワードでラップしたりして**してはならない** (MUST NOT)。

同一の出力を生成するために、包含するスキーマ文書内の、以前は外部にあったスキーマ・リソースへの参照は**変更してはならない** (MUST NOT)。そして、埋め込まれたスキーマ・リソースの"$id"を使用してスキーマに解決される必要がある。このような同一の出力には、検証評価と、結果として得られる注釈またはエラーで使用されるURIまたはパスが含まれる。

バンドル処理は複合スキーマ文書を作成する主な方法となることが多いが、個々のスキーマ・リソースが以前は単独で存在していなくても、手動で作成することも可能であり、またそれが期待される。

9.3.2. 異なる方言とデフォルトの方言

単一の文書に複数のスキーマ・リソースが存在する場合、どの方言で処理するべきかを定義していないスキーマ・リソースは、包含するリソースと同じ方言で処理**しなければならない** (MUST)。

参照可能なスキーマはすべて埋め込むことができるため、埋め込まれたスキーマ・リソースは、包含するリソースの"$schema"値を使用して、異なる処理方言を指定できる (MAY)。

9.3.3. 検証

複合スキーマ文書には、異なる方言を使用すると識別される埋め込みリソースが含まれている可能性があるため、メタスキーマを複合スキーマ文書にインスタンスとして適用してこれらの文書を検証するべきではない (SHOULD NOT)。スキーマ文書を検証するために代替の検証プロセスを提供することを推奨する (RECOMMENDED)。各スキーマ・リソースは、関連付けられたメタスキーマに対して個別に検証されるべきである (SHOULD)。 検証対象がスキーマであることがわかっている場合、"$id"の使用によって、スキーマが複合スキーマ文書であるかどうかを識別できます。これは、文書のルートではなく使用されている場合に埋め込みリソースを識別します。

すべての埋め込みリソースが同じ方言を使用していると識別される複合スキーマ文書、または"$schema"が省略され、したがって包含リソースの方言がデフォルトとなる複合スキーマ文書は、適切なメタスキーマを適用して検証できる (MAY)。

9.4. 注意事項

9.4.1. 無限再帰の防止

スキーマは、インスタンスに対して無限ループに陥ってはならない (MUST NOT)。たとえば、2つのスキーマ「#alice」と「#bob」の両方に、互いを参照する「allOf」プロパティがある場合、単純な検証器はインスタンスの検証を試みる際に無限の再帰ループに陥る可能性がある。スキーマは、このような無限の再帰的ネストを使用すべきではない (SHOULD NOT)。その動作は未定義である。

9.4.2. 可能性のある非スキーマへの参照

サブスキーマオブジェクト(またはブール値)は、既知の適用子キーワード、または1つ以上のサブスキーマを値として取る"$defs" (8.2.4節)などの場所を予約するキーワードと共に使用することで認識される。これらのキーワードは、「$defs」とこの文書からの標準的な適用子、または既知のボキャブラリからの拡張キーワード、あるいは実装固有のカスタムキーワードである可能性がある。

不明なキーワードの多階層構造は、ネストされたサブスキーマを導入する可能性があり、これは"$id"の処理ルールに従う。したがって、そのような認識されない構造内の参照ターゲットを確実に実装することはできず、結果として生じる動作は未定義である。同様に、既知のキーワードの下にある参照ターゲットで、その値がスキーマではないことがわかっている場合、実装にそのようなターゲットを検出する負担をかけるのを避けるために、動作は未定義となる。 これらのシナリオは、HTTP経由でスキーマを取得するが、application/schema+json以外のContent-Typeの応答を受信するのに類似しています。実装は確かにそれをスキーマとして解釈しようと試みることができますが、オリジンサーバーはそれが実際にそのようなものであるという保証を提供していません。したがって、それをそのようなものとして解釈することはセキュリティ上の問題を引き起こし、予測できない結果を招く可能性があります。

"$defs"と同一の構文とセマンティクスを持つ単一レベルのカスタムキーワードは、介入する"$id"キーワードを許可しないため、参照ターゲットをスキーマとして使用しようとする実装下では正しく動作する。しかし、この動作は実装固有であり、相互運用性のために依存してはならない (MUST NOT)。

9.5. インスタンスとスキーマの関連付け

9.5.1. ハイパーメディアの使用方法

JSONは、自動化されたAPIとロボットのためにHTTPサーバーによって広く採用されてきた。このセクションでは、メディアタイプとWebリンク [RFC8288]をサポートするプロトコルと共に使用する場合、よりRESTfulな方法でJSON文書の処理を強化する方法について説明する。

9.5.1.1. スキーマへのリンク

スキーマによって記述されたインスタンスは、Linked Data Protocol 1.0、8.1節 [W3C.REC-ldp-20150226]で定義されているように、「describedby」リンクリレーションを使用して、ダウンロード可能なJSONスキーマへのリンクを提供することを推奨する (RECOMMENDED)。

HTTPでは、そのようなリンクはLinkヘッダー [RFC8288]を使用して任意の応答に添付できる。そのようなヘッダーの例を以下に示す。

        Link: <https://example.com/my-hyper-schema>; rel="describedby"

9.5.1.2. HTTP経由での使用

ネットワーク経由のハイパーメディアシステムに使用される場合、HTTP [RFC7231]はスキーマを配布するためのプロトコルとして頻繁に選択される。不正なクライアントは、スキーマを長時間キャッシュできるのに、ネットワーク経由で必要以上に頻繁にスキーマを取得する場合、サーバー管理者にとって問題となる可能性がある。

HTTPサーバーは、JSONスキーマに対して長期間有効なキャッシュヘッダーを設定するべきである (SHOULD)。HTTPクライアントは、キャッシュヘッダーを遵守し、その有効期限内に文書を再要求してはならない (SHOULD)。分散システムは、共有キャッシュやキャッシュプロキシを使用するべきである (SHOULD)。

クライアントは、JSONスキーマの実装またはソフトウェア製品に固有のUser-Agentヘッダーを設定または追加するべきである (SHOULD)。記号は重要度の降順でリストされているため、JSONスキーマライブラリの名前/バージョンは、より一般的なHTTPライブラリの名前(存在する場合)の前にあるべきである。例を以下に示す。

        User-Agent: product-name/5.4.1 so-cool-json-schema/1.0.2 curl/7.43.0

クライアントは、「From」ヘッダーを使用してリクエストを行うことができ、サーバーオペレーターは、可能性のある不正なスクリプトの所有者に連絡できるようになるべきである (SHOULD)。

10. サブスキーマを適用するためのボキャブラリ

このセクションでは、他のボキャブラリの基礎として使用する**推奨される** (RECOMMENDED) 適用子キーワードのボキャブラリを定義する。

"$vocabulary"を使用しないメタスキーマは、そのURIがtrueの値で存在する場合と同様に、このボキャブラリを必要とするものとみなされるべきである (SHOULD)。

適用子ボキャブラリとして知られるこのボキャブラリの現在のURIは次のとおりです。<https://json-schema.dokyumento.jp/draft/2020-12/vocab/applicator>。

対応するメタスキーマの現在のURIは次のとおりです。https://json-schema.dokyumento.jp/draft/2020-12/meta/applicator

10.1. キーワードの独立性

スキーマキーワードは通常、互いの結果に影響を与えることなく、独立して動作する。

スキーマ作成者の便宜上、このボキャブラリ内のキーワードにはいくつかの例外がある。

10.2. サブスキーマを適用するためのキーワード

これらのキーワードは、親スキーマが適用されているインスタンスと同じ場所にサブスキーマを適用する。これにより、サブスキーマの結果をさまざまな方法で組み合わせたり、変更したりできる。

これらのキーワードのサブスキーマは、インスタンスを完全に独立して評価するため、1つのサブスキーマの結果が兄弟サブスキーマの結果に影響を与えるべきではない (MUST NOT)。したがって、サブスキーマは任意の順序で適用できる。

10.2.1. 論理を使用してサブスキーマを適用するためのキーワード

これらのキーワードは、サブスキーマのブール値の表明結果を組み合わせたり変更したりするための論理演算子に対応する。注釈の収集には直接的な影響を与えないが、同じ注釈キーワードを異なる値でインスタンスの位置に適用できるようになる。注釈キーワードは、そのような値を組み合わせるための独自のルールを定義する。

10.2.1.1. allOf

このキーワードの値は、空でない配列**でなければなりません**。配列の各要素は、有効なJSONスキーマ**でなければなりません**。

インスタンスがこのキーワードに対して正常に検証されるのは、このキーワードの値によって定義されたすべてのスキーマに対して正常に検証される場合です。

10.2.1.2. anyOf

このキーワードの値は、空でない配列**でなければなりません**。配列の各要素は、有効なJSONスキーマ**でなければなりません**。

インスタンスがこのキーワードに対して正常に検証されるのは、このキーワードの値によって定義された少なくとも1つのスキーマに対して正常に検証される場合です。アノテーションが収集されている場合、各サブスキーマからアノテーションが収集されるように、すべてのサブスキーマを検査**しなければなりません**。

10.2.1.3. oneOf

このキーワードの値は、空でない配列**でなければなりません**。配列の各要素は、有効なJSONスキーマ**でなければなりません**。

インスタンスがこのキーワードに対して正常に検証されるのは、このキーワードの値によって定義された正確に1つのスキーマに対して正常に検証される場合です。

10.2.1.4. not

このキーワードの値は、有効なJSONスキーマ**でなければなりません**。

インスタンスがこのキーワードに対して有効なのは、このキーワードによって定義されたスキーマに対して正常に検証に失敗する場合です。

10.2.2. 条件付きでサブスキーマを適用するためのキーワード

これらのキーワードの3つは、別のサブスキーマの結果に基づいてサブスキーマの条件付き適用を実装するために連携して動作します。4つ目は、特定の条件付きケースのショートカットです。

"if"、"then"、および"else"は、サブスキーマの境界を越えて相互作用**してはなりません**。言い換えれば、"allOf"の1つのブランチにある"if"は、別のブランチにある"then"または"else"に影響を与えては**なりません**。

"if"、"then"、または"else"が存在しない場合、デフォルトの動作はありません。"if"が存在しない場合、"then"と"else"の両方が完全に無視されるべきであり、空のスキーマが存在する場合として扱っては**なりません**。

10.2.2.1. if

このキーワードの値は、有効なJSONスキーマ**でなければなりません**。

このキーワードのサブスキーマの検証結果は、全体の検証結果に直接影響を与えません。むしろ、"then"または"else"のどちらのキーワードが評価されるかを制御します。

このキーワードのサブスキーマに対して正常に検証されたインスタンスは、存在する場合、「then」キーワードのサブスキーマ値に対しても有効**でなければなりません**。

このキーワードのサブスキーマに対して検証に失敗したインスタンスは、存在する場合、「else」キーワードのサブスキーマ値に対しても有効**でなければなりません**。

アノテーション (セクション7.7)が収集されている場合、キーワードが"then"または"else"なしで存在する場合も含め、このキーワードのサブスキーマから通常どおり収集されます。

10.2.2.2. then

このキーワードの値は、有効なJSONスキーマ**でなければなりません**。

"if"が存在し、インスタンスがそのサブスキーマに対して正常に検証された場合、インスタンスがこのキーワードのサブスキーマに対しても正常に検証された場合、このキーワードに対する検証は成功します。

"if"が存在しない場合、またはインスタンスがそのサブスキーマに対して検証に失敗した場合、このキーワードは効果がありません。そのような場合、実装は検証またはアノテーション収集の目的で、このキーワードに対してインスタンスを評価しては**なりません**。

10.2.2.3. else

このキーワードの値は、有効なJSONスキーマ**でなければなりません**。

"if"が存在し、インスタンスがそのサブスキーマに対して検証に失敗した場合、インスタンスがこのキーワードのサブスキーマに対して正常に検証された場合、このキーワードに対する検証は成功します。

"if"が存在しない場合、またはインスタンスがそのサブスキーマに対して正常に検証された場合、このキーワードは効果がありません。そのような場合、実装は検証またはアノテーション収集の目的で、このキーワードに対してインスタンスを評価しては**なりません**。

10.2.2.4. dependentSchemas

このキーワードは、インスタンスがオブジェクトであり、特定のプロパティが含まれている場合に評価されるサブスキーマを指定します。

このキーワードの値はオブジェクト**でなければなりません**。オブジェクトの各値は、有効なJSONスキーマ**でなければなりません**。

オブジェクトキーがインスタンス内のプロパティである場合、インスタンス全体がサブスキーマに対して検証される**必要があります**。その使用は、プロパティの存在に依存します。

このキーワードを省略すると、空のオブジェクトと同じ動作になります。

10.3. 子インスタンスにサブスキーマを適用するためのキーワード

これらのキーワードはそれぞれ、サブスキーマを子インスタンス(具体的にはオブジェクトのプロパティと配列の要素)に適用し、その結果を組み合わせるためのルールを定義します。

10.3.1. 配列にサブスキーマを適用するためのキーワード

10.3.1.1. prefixItems

"prefixItems"の値は、有効なJSONスキーマの空でない配列**でなければなりません**。

インスタンスの各要素が、存在する場合、同じ位置のスキーマに対して検証された場合、検証は成功します。このキーワードは配列の長さを制約しません。配列がこのキーワードの値より長い場合、このキーワードは一致する長さのプレフィックスのみを検証します。

このキーワードは、このキーワードがサブスキーマを適用した最大のインデックスであるアノテーション値を生成します。"items"キーワードによって生成されるものなど、サブスキーマがインスタンスのすべてのインデックスに適用された場合は、値はブール値trueになる場合があります。このアノテーションは"items"と"unevaluatedItems"の動作に影響を与えます。

このキーワードを省略すると、空の配列と同じアサーション動作になります。

10.3.1.2. items

"items"の値は、有効なJSONスキーマ**でなければなりません**。

このキーワードは、そのサブスキーマを、"prefixItems"キーワードのアノテーション結果によって報告された、同じスキーマオブジェクト内の"prefixItems"配列の長さよりも大きいインデックスにあるすべてのインスタンス要素に適用します。そのようなアノテーション結果が存在しない場合、"items"はすべてのインスタンス配列要素にそのサブスキーマを適用します。 "prefixItems"がない場合の"items"の動作は、以前のドラフトの"items"のスキーマ形式とまったく同じであることに注意してください。"prefixItems"が存在する場合、"items"の動作は以前の"additionalItems"キーワードとまったく同じです。

"items"サブスキーマがインスタンス配列内の任意の位置に適用された場合、ブール値trueのアノテーション結果を生成し、残りの配列要素すべてがこのキーワードのサブスキーマに対して評価されたことを示します。このアノテーションは、Unevaluatedボキャブラリ内の"unevaluatedItems"の動作に影響を与えます。

このキーワードを省略すると、空のスキーマと同じアサーション動作になります。

実装は、"prefixItems"配列の存在とサイズを直接チェックすることなど、同じ効果を生む別の方法でこのキーワードを実装または最適化することを選択できます。アノテーションの収集をサポートしていない実装は、そうする**必要があります**。

10.3.1.3. contains

このキーワードの値は、有効なJSONスキーマ**でなければなりません**。

"minContains"が存在し、値が0の場合を除き、配列インスタンスは、その要素の少なくとも1つが指定されたスキーマに対して有効である場合、「contains」に対して有効です。その場合、要素のいずれも指定されたスキーマに対して有効でない場合でも、配列インスタンスは「contains」キーワードに対して有効と見なす**必要があります**。

このキーワードは、そのサブスキーマを適用したときにこのキーワードが正常に検証されたインデックスの配列であるアノテーション値を生成します(昇順)。サブスキーマがインスタンスのすべてのインデックスに適用されたときに正常に検証される場合、値はブール値「true」になる場合があります。このキーワードのスキーマが適用されるインスタンス配列が空の場合、アノテーションが存在**しなければなりません**。

このアノテーションは、Unevaluatedボキャブラリ内の"unevaluatedItems"の動作に影響を与え、Validationボキャブラリ内の"minContains"および"maxContains"キーワードを実装するためにも使用できます。

最初のマッチが見つかった後でも、他のキーワードで使用するためのアノテーションを収集するために、サブスキーマはすべての配列要素に適用される**必要があります**。これは、すべての可能なアノテーションが収集されるようにするためです。

10.3.2. オブジェクトにサブスキーマを適用するためのキーワード

10.3.2.1. properties

"properties"の値はオブジェクト**でなければなりません**。このオブジェクトの各値は有効なJSONスキーマ**でなければなりません**。

インスタンスとこのキーワードの値の両方に出現する各名前について、その名前の子供インスタンスが対応するスキーマに対して正常に検証された場合、検証は成功します。

このキーワードの注釈結果は、このキーワードによって一致したインスタンスのプロパティ名の集合です。この注釈は、「additionalProperties」(この語彙内)と「unevaluatedProperties」(Unevaluated語彙内)の動作に影響します。

このキーワードを省略した場合、空のオブジェクトと同じアサーション動作になります。

10.3.2.2. patternProperties

"patternProperties"の値はオブジェクト**でなければなりません**。このオブジェクトのプロパティ名のそれぞれは、ECMA-262正規表現ダイアレクトに従って、有効な正規表現**であるべきです**。このオブジェクトのプロパティ値のそれぞれは、有効なJSONスキーマ**でなければなりません**。

インスタンス名と、このキーワードの値のプロパティ名として出現する正規表現のいずれかとが一致する場合、その名前の子供インスタンスが一致する正規表現に対応する各スキーマに対して正常に検証された場合、検証は成功します。

このキーワードの注釈結果は、このキーワードによって一致したインスタンスのプロパティ名の集合です。この注釈は、「additionalProperties」(この語彙内)と「unevaluatedProperties」(Unevaluated語彙内)の動作に影響します。

このキーワードを省略した場合、空のオブジェクトと同じアサーション動作になります。

10.3.2.3. additionalProperties

"additionalProperties"の値は、有効なJSONスキーマ**でなければなりません**。

このキーワードの動作は、同じスキーマオブジェクト内の「properties」と「patternProperties」の存在と注釈結果によって異なります。「additionalProperties」による検証は、「properties」または「patternProperties」の注釈結果に現れないインスタンス名の子供値にのみ適用されます。

そのようなすべてのプロパティについて、子供インスタンスが「additionalProperties」スキーマに対して検証された場合、検証は成功します。

このキーワードの注釈結果は、このキーワードのサブスキーマによって検証されたインスタンスのプロパティ名の集合です。この注釈は、Unevaluated語彙内の「unevaluatedProperties」の動作に影響します。

このキーワードを省略した場合、空のスキーマと同じアサーション動作になります。

実装では、同じ効果を生む別の方法(例:「properties」の名前と「patternProperties」のパターンをインスタンスのプロパティセットに対して直接確認する方法)で、このキーワードを実装または最適化することを選択しても構いません。注釈の収集をサポートしていない実装は、そうする**必要があります**。 このオプションを定義することで、出力形式に曖昧性が生じる可能性があります。この曖昧さは検証結果には影響しませんが、結果として得られる出力形式には影響します。この曖昧性により、注釈を使用するかどうか、またはドラフト-07と同じ効果を生む解決策を使用するかどうかによって、複数の有効な出力結果が得られます。失敗したスキーマからの注釈は削除されることは理解されています。詳細については、[意思決定記録](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)を参照してください。

10.3.2.4. propertyNames

"propertyNames"の値は、有効なJSONスキーマ**でなければなりません**。

インスタンスがオブジェクトの場合、このキーワードは、インスタンス内のすべてのプロパティ名が提供されたスキーマに対して検証されるかどうかを検証します。スキーマがテストするプロパティ名は常に文字列であることに注意してください。

このキーワードを省略した場合、空のスキーマと同じ動作になります。

11. 評価されていない場所のための語彙

これらのキーワードの目的は、スキーマ作成者が、隣接するキーワードの動的スコープのサブスキーマに対して正常に評価されていない配列項目またはオブジェクトプロパティにサブスキーマを適用できるようにすることです。

これらのインスタンス項目またはプロパティは、「anyOf」の分岐内のアサーションが失敗した場合など、1つ以上の隣接するキーワードサブスキーマに対して評価に失敗している可能性があります。そのような評価の失敗は、項目またはプロパティが評価されているかどうかには影響しません。成功した評価のみが考慮されます。

配列内の項目またはオブジェクトのプロパティが「正常に評価された」場合、それは期待されるオブジェクトまたは配列の表現に関して論理的に有効と見なされます。たとえば、2〜4個の車輪を必要とする車を表すサブスキーマがあり、「車輪」の値が6の場合、インスタンスオブジェクトは車として「評価されず」、「車輪」プロパティは「(既知のものとして正常に)評価されていない」と見なされ、注釈は保持されません。

隣接するキーワードとは、同じスキーマオブジェクト内のキーワードであり、動的スコープのサブスキーマには参照ターゲットと字句的なサブスキーマの両方が含まれることを思い出してください。

これらのキーワードの動作は、検証対象のインスタンスの場所に適用される隣接するキーワードの注釈結果によって異なります。

"$vocabulary"を使用しないメタスキーマは、そのURIがtrueの値で存在する場合と同様に、この語彙を必要とするものと見なされる**べきです**。

Unevaluated適用プログラム語彙として知られるこの語彙の現在のURIは、次のとおりです。<https://json-schema.dokyumento.jp/draft/2020-12/vocab/unevaluated>。

対応するメタスキーマの現在のURIは次のとおりです。https://json-schema.dokyumento.jp/draft/2020-12/meta/unevaluated

11.1. キーワードの独立性

スキーマキーワードは通常、互いの結果に影響を与えることなく、独立して動作します。ただし、この語彙内のキーワードは注目すべき例外です。

11.2. unevaluatedItems

"unevaluatedItems"の値は、有効なJSONスキーマ**でなければなりません**。

このキーワードの動作は、検証対象のインスタンスの場所に適用される隣接するキーワードの注釈結果によって異なります。具体的には、「prefixItems」、「items」、「contains」からの注釈で、これらは「unevaluatedItems」キーワードに隣接している場合にこれらのキーワードから取得できます。これら3つの注釈と「unevaluatedItems」は、すべての隣接するインプレース適用プログラム (セクション10.2)キーワードからも得られます。これには、このドキュメントで定義されているインプレース適用プログラムが含まれますが、それらに限定されません。

関連する注釈が存在しない場合、「unevaluatedItems」サブスキーマは配列内のすべての場所に適用される**必要があります**。関連する注釈のいずれかからブール値trueが存在する場合、「unevaluatedItems」は無視される**必要があります**。それ以外の場合は、サブスキーマは「prefixItems」の最大の注釈値よりも大きいインデックスに適用される**必要があります**。「prefixItems」の注釈値には、「contains」の注釈値は含まれません。

これは、「prefixItems」、「items」、「contains」、およびすべてのインプレース適用プログラムは、このキーワードを評価する前に評価される**必要がある**ことを意味します。拡張キーワードの作者は、このキーワードの後に評価される必要があるインプレース適用プログラムを定義してはいけません。

"unevaluatedItems"サブスキーマがインスタンス配列内の任意の位置に適用された場合、「items」の動作と同様に、ブール値trueの注釈結果が生成されます。この注釈は、親スキーマ内の「unevaluatedItems」の動作に影響します。

このキーワードを省略した場合、空のスキーマと同じアサーション動作になります。

11.3. unevaluatedProperties

"unevaluatedProperties"の値は、有効なJSONスキーマ**でなければなりません**。

このキーワードの動作は、検証対象のインスタンスの場所に適用される隣接するキーワードの注釈結果によって異なります。具体的には、「properties」、「patternProperties」、「additionalProperties」からの注釈で、これらは「unevaluatedProperties」キーワードに隣接している場合にこれらのキーワードから取得できます。これら3つの注釈と「unevaluatedProperties」は、すべての隣接するインプレース適用プログラム (セクション10.2)キーワードからも得られます。これには、このドキュメントで定義されているインプレース適用プログラムが含まれますが、それらに限定されません。

"unevaluatedProperties"による検証は、検証対象のインスタンスの場所に適用される「properties」、「patternProperties」、「additionalProperties」、または「unevaluatedProperties」の注釈結果に現れないインスタンス名の子供値にのみ適用されます。

そのようなすべてのプロパティについて、子供インスタンスが「unevaluatedProperties」スキーマに対して検証された場合、検証は成功します。

これは、「properties」、「patternProperties」、「additionalProperties」、およびすべてのインプレース適用プログラムは、このキーワードを評価する前に評価される**必要がある**ことを意味します。拡張キーワードの作者は、このキーワードの後に評価される必要があるインプレース適用プログラムを定義してはいけません。

このキーワードの注釈結果は、このキーワードのサブスキーマによって検証されたインスタンスのプロパティ名の集合です。この注釈は、親スキーマ内の「unevaluatedProperties」の動作に影響します。

このキーワードを省略した場合、空のスキーマと同じアサーション動作になります。

12. 出力フォーマット

JSONスキーマはプラットフォームに依存しないように定義されています。そのため、プラットフォーム間での互換性を高めるために、実装は標準的な検証出力形式に準拠する**べきです**。このセクションでは、検証結果を正しく解釈するために、利用者が必要とする最低限の要件について説明します。

12.1. フォーマット

JSON スキーマ出力は、4.2.1項で説明されているJSON スキーマデータインスタンスモデルを使用して定義されます。実装は、特定の言語とプラットフォームでサポートされている限り、これと異なる場合があります。ただし、出力は、シリアル化などの手段によって、ここに定義されているJSON形式に変換可能であることが推奨されます。

12.2. 出力形式

この仕様では、4つの出力形式を定義しています。「出力構造」セクションで、各形式の要件を参照してください。

  • フラグ - 詳細情報のない、検証結果全体を単純に示すブール値。
  • 基本 - 検証情報をフラットなリスト構造で提供します。
  • 詳細 - スキーマの構造に基づいた、凝縮された階層構造で検証情報を提供します。
  • 冗長 - スキーマの正確な構造と一致する、凝縮されていない階層構造で検証情報を提供します。

実装では、「フラグ」、「基本」、または「詳細」形式の少なくとも1つを提供する必要があり、「冗長」形式を提供しても構いません。「詳細」または「冗長」形式の1つ以上を提供する場合は、「フラグ」形式も提供する必要があります。実装では、サポートする形式をドキュメントに指定する必要があります。

12.3. 最小情報

単純な「フラグ」出力以外にも、スキーマまたはインスタンスのデバッグに役立つ追加情報があります。各サブ結果には、少なくともこのセクションに含まれる情報を含める必要があります。

これらのコンポーネントすべてを含む単一のオブジェクトが出力単位と見なされます。

実装では、追加情報を提供することもできます。

12.3.1. キーワードの相対位置

検証パスに続く検証キーワードの相対位置。値はJSONポインタで表現する必要があり、「$ref」や「$dynamicRef」などの参照による適用子を含める必要があります。

/properties/width/$ref/minimum

これらの参照による適用子キーワードが含まれているため、このポインタは通常のJSONポインタプロセスでは解決できない場合があります。

この情報のJSONキーは「keywordLocation」です。

12.3.2. キーワードの絶対位置

検証キーワードの絶対的な、参照解決済みの位置。値は、関連するスキーマリソースの正規URIとJSONポインタフラグメントを使用して完全なURIで表現する必要があり、「$ref」や「$dynamicRef」などの参照による適用子を非終端パスコンポーネントとして含めることはできません。エラーまたは注釈がそのキーワード(解決できない参照など)の場合、そのようなキーワードで終わる場合があります。 ここで「絶対」とは、「絶対ファイルシステムパス」(完全な場所を意味する)という意味であり、RFC 3986の「絶対URI」用語(スキームを含むがフラグメントを含まないという意味)とは異なります。キーワードの絶対位置には、キーワードを識別するためのフラグメントが含まれます。

https://example.com/schemas/common#/$defs/count/minimum

動的スコープが参照を渡さなかった場合、またはスキーマが絶対URIを「$id」として宣言していない場合にのみ、この情報を省略できます。

この情報のJSONキーは「absoluteKeywordLocation」です。

12.3.3. インスタンスの位置

検証対象のインスタンス内のJSON値の位置。値はJSONポインタで表現する必要があります。

この情報のJSONキーは「instanceLocation」です。

12.3.4. エラーまたは注釈

検証によって生成されるエラーまたは注釈。

エラーの場合、メッセージの具体的な言葉遣いはこの仕様では定義されていません。実装ではこれらを提示する必要があります。

注釈の場合、注釈を生成する各キーワードは、その形式を指定します。デフォルトでは、キーワードの値です。

検証に失敗した際のJSONキーは「error」、検証に成功した際のJSONキーは「annotation」です。

12.3.5. ネストされた結果

2つの階層構造の場合、このプロパティはネストされたエラーと注釈を保持します。

検証に失敗した際のネストされた結果のJSONキーは「errors」、検証に成功した際のJSONキーは「annotations」です。キーワードにネストされた結果がある場合でも、ローカルエラーまたは注釈を持つことができるため、複数形を使用してください。

12.4. 出力構造

出力は、「valid」という名前のブール値のプロパティを含むオブジェクトである必要があります。結果に関する追加情報が必要な場合、出力には以下のように「errors」または「annotations」も含まれている必要があります。

  • 「valid」- 検証の成功または失敗を示すブール値
  • 「errors」- 検証失敗によって生成されたエラーまたは注釈のコレクション
  • 「annotations」- 検証成功によって生成されたエラーまたは注釈のコレクション

これらの例では、次のスキーマとインスタンスが使用されます。

{
  "$id": "https://example.com/polygon",
  "$schema": "https://json-schema.dokyumento.jp/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
  }
]

このインスタンスは検証に失敗し、エラーを生成しますが、注釈を生成する合格スキーマの例を推測するのは簡単です。

具体的には、生成されるエラーは次のとおりです。

  • 2番目のオブジェクトには「y」プロパティがありません。
  • 2番目のオブジェクトには、許可されていない「z」プロパティがあります。
  • オブジェクトは2つだけですが、3つ必要です。

これらの例に示されているエラーメッセージの言葉遣いは、この仕様の要件ではありません。実装では、対象者向けに調整されたエラーメッセージを作成するか、ユーザーが独自のメッセージを作成できるテンプレートメカニズムを提供する必要があります。

12.4.1. フラグ

最も単純なケースでは、「valid」プロパティのブール値の結果を満たすだけで済みます。

{
  "valid": false
}

この形式ではエラーや注釈が返されないため、結果を決定できるようになったらすぐに失敗または成功を返すショートサーキットロジックを使用することが推奨されます。たとえば、「anyOf」キーワードに5つのサブスキーマが含まれており、2番目のサブスキーマが合格した場合、他の3つのサブスキーマを確認する必要はありません。ロジックは単に成功で返すことができます。

12.4.2. 基本

「基本」構造は、出力単位のフラットなリストです。

{
  "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"
    }
  ]
}

12.4.3. 詳細

「詳細」構造はスキーマに基づいており、人間と機械の両方にとってより読みやすくなる可能性があります。このように構造を整理することで、エラー間の関連付けがより明確になります。たとえば、「y」プロパティの欠落と余分な「z」プロパティの両方が、インスタンスの同じ場所から発生しているという事実は、「基本」構造ではすぐに明らかではありません。階層では、相関関係をより簡単に識別できます。

結果オブジェクトの構築には、次の規則が適用されます。

  • すべての適用子キーワード(「*Of」、「$ref」、「if/then/else」など)にはノードが必要です。
  • 子を持たないノードは削除されます。
  • 子ノードが1つだけのノードは、その子ノードに置き換えられます。

ブランチノードには、エラーメッセージや注釈は必要ありません。

{
  "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"
    }
  ]
}

12.4.4. 冗長

「冗長」構造は、スキーマと完全に一致する完全に実現された階層です。この構造は、エラーの位置が重要なフォームの生成と検証に適用されます。

これと「詳細」構造の主な違いは、すべての結果が返されることです。これには、削除されるサブスキーマ検証結果(たとえば、「not」キーワード内の検証に失敗した検証、検証に成功した検証など)も含まれます。このため、各ノードにも`valid`プロパティを含めて、そのノードの検証結果を示すことが推奨されます。

この出力構造は非常に大きくなる可能性があるため、簡潔にするために小さな例を示します。上記の例の完全な出力構造のURIは次のとおりです。https://json-schema.dokyumento.jp/draft/2020-12/output/verbose-example

// schema
{
  "$id": "https://example.com/polygon",
  "$schema": "https://json-schema.dokyumento.jp/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."
        }
      ]
    }
  ]
}

12.4.5. 出力検証スキーマ

便宜上、実装によって生成された出力を検証するためのJSONスキーマが提供されています。そのURIは次のとおりです。https://json-schema.dokyumento.jp/draft/2020-12/output/schema

13. セキュリティに関する考慮事項

スキーマとインスタンスの両方ともJSON値です。そのため、RFC 8259 [RFC8259]で定義されているすべてのセキュリティに関する考慮事項が適用されます。

インスタンスとスキーマは両方とも、多くの場合、信頼できないサードパーティによって記述され、パブリックインターネットサーバーに展開されます。バリデーターは、スキーマに対する解析と検証が過剰なシステムリソースを消費しないように注意する必要があります。バリデーターは無限ループに陥ってはいけません。

悪意のあるパーティによって、実装が非常に大きな値のコピーを注釈として繰り返し収集するように強制される可能性があります。実装では、このようなシナリオでシステムリソースの過剰な消費を防ぐ必要があります。

サーバーは、悪意のあるパーティが、既存の「$id」と同一または非常に類似した「$id」を持つスキーマをアップロードすることで、既存のスキーマの機能を変更できないようにする必要があります。

個々のJSONスキーマボキャブラリにも、独自のセキュリティに関する考慮事項がある可能性があります。詳細については、それぞれの仕様を参照してください。

スキーマ作成者は、「$comment」の内容に注意する必要があります。悪意のある実装では、仕様に違反してエンドユーザーに表示したり、そのような動作が期待されている場合でも削除に失敗したりする可能性があります。

悪意のあるスキーマ作成者は、「$comment」内に実行可能コードやその他の危険な素材を配置する可能性があります。実装は、「$comment」の内容に基づいて解析したり、その他の処理を行ってはなりません。

14. IANAに関する考慮事項

14.1. application/schema+json

JSONスキーマで提案されているMIMEメディアタイプは、以下のとおり定義されています。

14.2. application/schema-instance+json

JSONスキーマ固有のメディアタイプを必要とするJSONスキーマインスタンスで提案されているMIMEメディアタイプは、以下のとおり定義されています。

15. 参考文献

15.1. 規定参照

[RFC2119]
Bradner, S."RFCにおける必須レベルを示すためのキーワード"BCP 14RFC 2119DOI 10.17487/RFC2119<https://www.rfc-editor.org/info/rfc2119>
[RFC3986]
Berners-Lee, T.Fielding, R.、およびL. Masinter"Uniform Resource Identifier (URI): 汎用構文"STD 66RFC 3986DOI 10.17487/RFC3986<https://www.rfc-editor.org/info/rfc3986>
[RFC6839]
Hansen, T.およびA. Melnikov"追加メディアタイプ構造化構文サフィックス"RFC 6839DOI 10.17487/RFC6839<https://www.rfc-editor.org/info/rfc6839>
[RFC6901]
Bryan, P., Ed.Zyp, K.、およびM. Nottingham, Ed."JavaScript Object Notation (JSON) ポインタ"RFC 6901DOI 10.17487/RFC6901<https://www.rfc-editor.org/info/rfc6901>
[RFC8259]
Bray, T., Ed."JavaScript Object Notation (JSON) データ交換形式"STD 90RFC 8259DOI 10.17487/RFC8259<https://www.rfc-editor.org/info/rfc8259>
[W3C.REC-ldp-20150226]
Speicher, S.Arwe, J.、およびA. Malhotra"Linked Data Platform 1.0"World Wide Web Consortium Recommendation REC-ldp-20150226<https://www.w3.org/TR/2015/REC-ldp-20150226>
[ecma262]
"ECMA-262、第11版仕様"<https://www.ecma-international.org/ecma-262/11.0/index.html>

15.2. 参考参照

[RFC6596]
Ohye, M.およびJ. Kupke"標準リンクリレーション"RFC 6596DOI 10.17487/RFC6596<https://www.rfc-editor.org/info/rfc6596>
[RFC7049]
Bormann, C.およびP. Hoffman"簡潔なバイナリオブジェクト表現(CBOR)"RFC 7049DOI 10.17487/RFC7049<https://www.rfc-editor.org/info/rfc7049>
[RFC7231]
Fielding, R., Ed.およびJ. Reschke, Ed."ハイパーテキスト転送プロトコル(HTTP/1.1): セマンティクスとコンテンツ"RFC 7231DOI 10.17487/RFC7231<https://www.rfc-editor.org/info/rfc7231>
[RFC8288]
Nottingham, M."Web Linking"RFC 8288DOI 10.17487/RFC8288<https://www.rfc-editor.org/info/rfc8288>
[W3C.WD-fragid-best-practices-20121025]
Tennison, J."フラグメント識別子とメディアタイプ定義に関するベストプラクティス"World Wide Web Consortium WD WD-fragid-best-practices-20121025<https://www.w3.org/TR/2012/WD-fragid-best-practices-20121025>
[json-schema-validation]
Wright, A.Andrews, H.、およびB. Hutton"JSONスキーマ検証: JSONの構造検証のためのボキャブラリ"開発中インターネットドラフト、draft-bhutton-json-schema-validation-01<https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-validation-01>
[json-hyper-schema]
Andrews, H.およびA. Wright"JSONハイパー-スキーマ: JSONのハイパーメディアアノテーションのためのボキャブラリ"開発中インターネットドラフト、draft-handrews-json-schema-hyperschema-02<https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-hyperschema-02>
[xml-names]
Bray, T., Ed.Hollander, D., Ed.Layman, A., Ed.、およびR. Tobin, Ed."XML名前空間1.1(第2版)"<http://www.w3.org/TR/2006/REC-xml-names11-20060816>

付録A. スキーマ識別例

ルートスキーマとさまざまなサブスキーマの両方を識別するために「$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ポインタ [RFC6901](ルートスキーマを基準とする)にあるスキーマは、以下のベースURIを持ち、上記のセクション5および9.2.1に従って、リストされている任意のURIで識別できます。

# (ドキュメントルート)
標準URI(およびベースURI)
https://example.com/root.json
標準リソースURIとポインタフラグメント
https://example.com/root.json#
#/$defs/A
ベースURI
https://example.com/root.json
標準リソースURIとプレーンフラグメント
https://example.com/root.json#foo
標準リソースURIとポインタフラグメント
https://example.com/root.json#/$defs/A
#/$defs/B
標準URI(およびベースURI)
https://example.com/other.json
標準リソースURIとポインタフラグメント
https://example.com/other.json#
包含する(root.json)リソースのベースURIとフラグメント
https://example.com/root.json#/$defs/B
#/$defs/B/$defs/X
ベースURI
https://example.com/other.json
標準リソースURIとプレーンフラグメント
https://example.com/other.json#bar
標準リソースURIとポインタフラグメント
https://example.com/other.json#/$defs/X
包含する(root.json)リソースのベースURIとフラグメント
https://example.com/root.json#/$defs/B/$defs/X
#/$defs/B/$defs/Y
標準URI(およびベースURI)
https://example.com/t/inner.json
標準URIとプレーンフラグメント
https://example.com/t/inner.json#bar
標準URIとポインタフラグメント
https://example.com/t/inner.json#
包含する(other.json)リソースのベースURIとフラグメント
https://example.com/other.json#/$defs/Y
包含する(root.json)リソースのベースURIとフラグメント
https://example.com/root.json#/$defs/B/$defs/Y
#/$defs/C
標準URI(およびベースURI)
urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f
標準URIとポインタフラグメント
urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f#
包含する(root.json)リソースのベースURIとフラグメント
https://example.com/root.json#/$defs/C

注: URIのフラグメント部分は、標準または非標準を決定するものではありません。むしろ、(任意のフラグメントを含む完全なURIの一部として使用される)ベースURIが、結果として得られる完全なURIの標準的な性質を決定します。複数の「標準」URI?これは混乱を招く可能性があることを認識しており、JSONポインタフラグメントと埋め込みスキーマリソースセクション9.2.1セクションにあるCREFを参照して、さらにコメントを確認してください。

付録B. スキーマドキュメントと参照の操作

参照("$ref")の出現方法や場所に基づいてスキーマ文書を再配置するために、さまざまなツールが作成されています。この付録では、この仕様に準拠するユースケースとアクションについて説明します。

B.1. スキーマリソースの単一文書へのバンドル

一緒に使用する目的のスキーマ・リソースのセットは、それぞれ独自のスキーマ文書に、すべて同じスキーマ文書に、またはその間の任意の粒度の文書グループ化で整理できます。

さまざまな種類の参照削除を実行する多くのツールが存在します。その一般的なケースは、すべての参照をそのファイル内で解決できる単一ファイルを作成することです。これは通常、配布を簡素化するため、またはJSONスキーマライブラリのさまざまな呼び出しが多数のリソースの追跡とロードを行う必要がないようにコーディングを簡素化するために実行されます。

すべての静的参照(例:「$ref」)が、標準リソースURIをベースとしてURIに解決されるURI参照を使用し、すべてのスキーマ・リソースがルートスキーマに絶対URIを"$id"として持つ限り、この変換は安全かつ可逆的に実行できます。

これらの条件が満たされると、各外部リソースを"$defs"の下にコピーしても、リソースのスキーマオブジェクト間の参照が壊れることなく、検証やアノテーションの結果のいかなる側面も変更されません。「$defs」下のスキーマの名前は、それぞれ一意であることを前提として動作に影響を与えません。埋め込まれたリソースの標準URIには表示されないためです。

B.2. 参照の削除は常に安全とは限らない

すべての参照を削除して単一のスキーマ文書を作成しようとすると、すべての場合において、元の形式と同じ動作をするスキーマが生成されるわけではありません。

"$ref"は現在、他のキーワードと同じスキーマオブジェクトに他のキーワードを許可する他のキーワードとして扱われるため、すべての場合において非再帰的な"$ref"削除を完全にサポートするには、比較的複雑なスキーマ操作が必要になる場合があります。スキーマ構造だけでなく、意図された用途にも依存するため、安全な"$ref"削除変換のセットを決定または提供することは、この仕様の範囲外です。

付録C. 再帰的スキーマ拡張の例

ツリー内の各ノードは任意の種類の "data" フィールドを持つことができる単純な再帰ツリー構造を記述する次の2つのスキーマを考えてみます。最初のスキーマは他のインスタンスプロパティを許可し、無視します。2番目はより厳格で、"data"と"children"プロパティのみを許可します。「data」が「daat」と誤って記述されたインスタンスの例も示されています。

// tree schema, extensible
{
    "$schema": "https://json-schema.dokyumento.jp/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.dokyumento.jp/draft/2020-12/schema",
    "$id": "https://example.com/strict-tree",
    "$dynamicAnchor": "node",

    "$ref": "tree",
    "unevaluatedProperties": false
}

// instance with misspelled field
{
    "children": [ { "daat": 1 } ]
}

これらの2つのスキーマを読み込むと、それぞれに存在する"$dynamicAnchor"の名前付き "node"(これが単なる名前であるため"#"がないことに注意)が表示され、次の完全なスキーマURIになります。

さらに、JSONスキーマの実装は、これらのフラグメントが"$dynamicAnchor"で作成されたことを追跡します。

インスタンスに「厳格なツリー」スキーマを適用すると、「$ref」に従って「ツリー」スキーマに移動し、「children」サブスキーマを調べ、「items」サブスキーマに「$dynamicRef」:to "#node"(URIフラグメント構文の"#"に注意)を見つけます。その参照は「https://example.com/tree#node」に解決され、これは「$dynamicAnchor」によって作成されたフラグメントを持つURIです。したがって、参照に従う前に動的スコープを調べる必要があります。

この時点で、動的パスは "#/$ref/properties/children/items/$dynamicRef" であり、動的スコープには(最外部スコープから最内部スコープまで)次のものが含まれます。

  1. "https://example.com/strict-tree#"
  2. "https://example.com/tree#"
  3. "https://example.com/tree#/properties/children"
  4. "https://example.com/tree#/properties/children/items"

プレーンネームフラグメントを探しているため、スキーマ・リソース内のどこでも定義できるため、JSONポインターフラグメントはこのチェックとは無関係です。つまり、これらのフラグメントを削除し、連続する重複を削除して、次のように生成できます。

  1. "https://example.com/strict-tree"
  2. "https://example.com/tree"

この場合、最外部のリソースにも"$dynamicAnchor"によって定義された"node"フラグメントがあります。したがって、「$dynamicRef」を「https://example.com/tree#node」に解決する代わりに、「https://example.com/strict-tree#node」に解決します。

このように、「tree」スキーマの再帰は「strict-tree」のルートに再帰し、「strict-tree」をインスタンスのルートに適用するだけでなく、「tree」をインスタンスの子に適用します。

この例では、各スキーマの同じ場所に、具体的にはリソースルートスキーマに、両方の"$dynamicAnchor"が表示されています。プレーンネームフラグメントはJSON構造とは独立しているため、ノードスキーマオブジェクトの1つまたは両方を"$defs"の下に移動した場合でも、同様に機能します。動的参照の解決方法を示すのは、一致する"$dynamicAnchor"の値であり、JSON構造の相関関係ではありません。

付録D. 語彙との連携

D.1. 語彙とメタスキーマ作成者のベストプラクティス

語彙の作成者は、語彙が幅広く使用され、他の語彙と組み合わされる可能性がある場合は、キーワード名の衝突を避けるように注意する必要があります。JSONスキーマは正式な名前空間システムを提供しませんが、キーワード名を制約することもなく、任意の数の名前空間アプローチを許可します。

語彙は、別の語彙からのキーワードの動作に関してキーワードの動作を定義するか、許容値の制限されたまたは拡張されたセットを持つ別の語彙からのキーワードを使用することなどによって、互いに構築できます。そのような語彙の再利用のすべてが、その上に構築されている語彙と互換性のある新しい語彙をもたらすわけではありません。語彙の作成者は、互換性のレベル(存在する場合)を明確に文書化する必要があります。

メタスキーマの作成者は、同じキーワードに対して競合する構文またはセマンティクスを定義する複数の語彙を組み合わせるために"$vocabulary"を使用しないでください。セマンティックの競合は一般的にスキーマ検証では検出できないため、実装ではそのような競合を検出することは想定されていません。競合する語彙が宣言されている場合、結果の動作は未定義です。

語彙の作成者は、語彙のキーワードの予期される使用を独自に検証するメタスキーマを提供する必要があります。そのようなメタスキーマは追加のキーワードを禁止するべきではなく、コア語彙からのキーワードを禁止してはなりません。

メタスキーマの作成者は、"allOf" (セクション10.2.1.1)キーワードを使用して各語彙のメタスキーマを参照することをお勧めしますが、特定のユースケースには、メタスキーマを作成するための他のメカニズムが適切な場合があります。

メタスキーマの再帰的な性質により、「$dynamicAnchor」および「$dynamicRef」キーワードは、検証メタスキーマを拡張するJSONハイパー・スキーマ・メタスキーマで見られるように、既存のメタスキーマを拡張するのに特に役立ちます。

メタスキーマは、宣言された語彙に関連付けられたメタスキーマが記述するもの以上に、追加の制約を課す可能性があり、語彙に存在しないキーワードを記述することも含みます。これにより、語彙のサブセットへの使用を制限し、再利用を意図しないローカルに定義されたキーワードを検証できます。

ただし、メタスキーマは、語彙が予期するJSON型とは異なる型を要求することなどによって、宣言する語彙と矛盾するべきではありません。結果の動作は未定義です。

任意の実装で語彙のサポートをテストする必要のない、ローカル使用を目的としたメタスキーマは、「$vocabulary」を完全に省略できます。

D.2. 語彙宣言を含むメタスキーマの例

このメタスキーマは、コアと適用者の語彙と拡張語彙の両方を明示的に宣言し、「allOf」でそれらのメタスキーマを組み合わせます。その語彙のキーワードのみを記述する拡張語彙のメタスキーマは、メインの例メタスキーマの後で示されています。

メインの例メタスキーマはまた、「unevaluated」で始まるプレフィックスが付いたキーワード(実装が特に複雑である)を禁止することによって、未評価語彙の使用を制限します。これは、他の語彙によって定義されたセマンティクスまたはキーワードのセットを変更しません。単に、このメタスキーマを使用するスキーマで「unevaluated」で始まるプレフィックスが付いたキーワードを使用しようとすると、このメタスキーマに対して検証が失敗することを保証します。

最後に、このメタスキーマは、どの語彙にも含まれていないキーワード「localKeyword」の構文を記述しています。おそらく、このメタスキーマの実装者とユーザーは、「localKeyword」のセマンティクスを理解するでしょう。JSONスキーマは、語彙以外のキーワードのセマンティクスを表すメカニズムを定義していないため、理解されている特定の環境を除いて、使用には適していません。

このメタスキーマは、一般的に使用するためにいくつかの語彙を組み合わせています。

{
  "$schema": "https://json-schema.dokyumento.jp/draft/2020-12/schema",
  "$id": "https://example.com/meta/general-use-example",
  "$dynamicAnchor": "meta",
  "$vocabulary": {
    "https://json-schema.dokyumento.jp/draft/2020-12/vocab/core": true,
    "https://json-schema.dokyumento.jp/draft/2020-12/vocab/applicator": true,
    "https://json-schema.dokyumento.jp/draft/2020-12/vocab/validation": true,
    "https://example.com/vocab/example-vocab": true
  },
  "allOf": [
    {"$ref": "https://json-schema.dokyumento.jp/draft/2020-12/meta/core"},
    {"$ref": "https://json-schema.dokyumento.jp/draft/2020-12/meta/applicator"},
    {"$ref": "https://json-schema.dokyumento.jp/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.dokyumento.jp/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"で参照される各単一語彙メタスキーマは対応する語彙を宣言していますが、この新しいメタスキーマではそれらを再宣言する必要があります。

コアと検証仕様で定義されたすべての語彙を組み合わせた標準メタスキーマと、それらの仕様とハイパー・スキーマ仕様で定義されたすべての語彙を組み合わせた標準メタスキーマは、さらに複雑な組み合わせを示しています。これらのメタスキーマのURIは、それぞれ検証仕様とハイパー・スキーマ仕様にあります。

汎用メタスキーマは"minDate"の構文を検証できますが、"minDate"のセマンティックな意味の背後にあるロジックを定義するのは語彙です。"minDate"のセマンティクス(この例では、インスタンス値はスキーマ内のキーワードの値として提供された日付以降の日付でなければならない)を理解せずに実装すると、構文的な使用方法のみを検証できます。この場合、日付形式の文字列であることを検証すること(検証仕様 [json-schema-validation]で説明されているように、"format"が純粋にアノテーションとして機能する場合でも、"pattern"を使用して検証されるようにします)。

付録E. 参照と生成的なユースケース

参照の存在は検証結果に対して透過的であることが期待されますが、コードジェネレーターや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番目はクラス関係が割り当てられていないため、コードジェネレーターは参照がないかのようにターゲットの定義をこれと組み合わせる必要があります。

プロパティを見ると、"foo"はオブジェクト合成としてフラグ付けされていますが、"date"プロパティはフラグ付けされていません。これは単にサブフィールドを持つフィールドであり、個別のクラスのインスタンスではありません。

この使用方法では、アノテーションを参照と同じオブジェクトに配置する必要があり、参照として認識可能である必要があります。

付録F. 謝辞

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の皆様に感謝いたします。

付録G. 変更ログ

インターネットドラフトのステータスを離れる前にこのセクションを削除してください。

draft-bhutton-json-schema-01
  • "type"、"contains"、"unevaluatedProperties"、"unevaluatedItems"キーワードの説明の改善と明確化
  • "標準URI"の様々な側面の明確化
  • アノテーションと"additionalProperties"に関する曖昧性に関するコメント
  • 語彙は正式に定義する必要がないことの明確化
  • 残りのメディアタイプパラメーターへの参照の削除
  • 複数の例を修正
draft-bhutton-json-schema-00
  • 埋め込みリソースの場合、"$schema"は変更される場合があります
  • 配列値の"items"機能は、現在"prefixItems"です
  • "items"は古い"additionalItems"の機能を包含します
  • "contains"アノテーションの動作と"contains"と"unevaluatedItems"の相互作用が指定されました
  • $recursive*を$dynamic*に名前変更し、動作を変更
  • $dynamicAnchorは$anchorのようなフラグメントを定義します
  • $dynamic*(以前は$recursive)は、ランタイムベースURIの決定をより以上使用しません
  • 複合スキーマドキュメント(バンドル)と処理を定義
  • 正規表現のサポートにはECMA-262第11版を参照
  • 正規表現はUnicodeをサポートする必要があります
  • メディアタイプパラメーターを削除
  • 未知のキーワードはアノテーションとして収集されることを指定
  • "unevaluatedItems"と"unevaluatedProperties"をコアから独自の語彙に移動
draft-handrews-json-schema-02
  • JSON仕様のRFC 8259への更新
  • "definitions"を検証仕様から"$defs"としてここに移動
  • 適用キーワードを検証仕様から独自の語彙として移動
  • "dependencies"のスキーマ形式を検証仕様から"dependentSchemas"として移動
  • アノテーションの収集を正式化
  • 推奨される出力形式を指定
  • アノテーションとアサーションの結果という観点からキーワードの相互作用を定義
  • "unevaluatedProperties"と"unevaluatedItems"を追加
  • アサーション、適用者、およびアノテーションモデルという観点から"$ref"の動作を定義
  • "$ref"に隣接するキーワードを許可
  • 未知のキーワードを含む"$ref"ターゲットの未定義の動作に注意
  • 主にメタスキーマの拡張のために再帰的な参照を追加
  • 正式な語彙の概念と、メタスキーマを通じてそれらをどのように認識できるかを追加
  • ネットワーク取得以外の初期ベースURIに関する追加のガイダンス
  • "application/schema+json"に"schema"メディアタイプパラメーターを許可
  • メディアタイプパラメーターとHTTP Acceptヘッダーのより良い説明
  • 標準およびベースの絶対URIのみを確立するために"$id"を使用し、フラグメントは使用しません
  • 単純な名前フラグメントのみの形式の"$id"を"$anchor"に置き換え
  • "$id"境界を超えたJSONポインターの動作は信頼できないことを明確化
draft-handrews-json-schema-01
  • このドラフトは純粋に明確化であり、機能的な変更はありません
  • JSON Schemaの主要な使用方法としてアノテーションを強調
  • ユースケースによる"$id"の明確化
  • 包括的なスキーマ識別例
  • "外部参照"を、実装が別のドキュメントからスキーマを知る方法と時期に置き換え
  • "内部参照"を実装が解析中にスキーマ識別子をどのように認識するべきかに置き換え
  • 以前の"内部"または"外部"参照の参照解除は、常に同じプロセスです
  • 小さな書式設定の改善
draft-handrews-json-schema-00
  • スキーマキーワード語彙の概念をより明確にする
  • "整数"の概念はデータモデルではなく語彙からのものであることに注意
  • キーワードをアサーションまたはアノテーションとして分類し、それらの一般的な動作を説明
  • 一般化されたアサーションという観点からブールスキーマを説明
  • スキーマに関するユーザーに表示されないメモには"$comment"を予約
  • "$id"とフラグメントに関する表現の改善
  • 再帰的な参照によるメタスキーマの拡張の課題に注意
  • "application/schema-instance+json"メディアタイプを追加
  • "profile"の代わりに"schema"リンクリレーション/パラメーターを推奨
draft-wright-json-schema-01
  • イントロの更新
  • 任意のスキーマをブール値にすることを許可
  • "$schema"はサブスキーマには表示されないようにする必要がありますが、変更される可能性があります
  • "id"を"$id"に変更。すべての主要なキーワードに"$"を接頭辞として追加
  • application/schema+jsonのフラグメントの明確化と正式化
  • JSONデータモデルで表すことができるCBORなどの形式への適用可能性に注意
draft-wright-json-schema-00
  • JSONへの参照の更新
  • HTTPへの参照の更新
  • JSONポインターへの参照の更新
  • "id"の動作は、現在RFC3986で指定されています
  • URIの語彙の使用をRFC3986と調整
  • draft-pbryan-zyp-json-ref-03への参照を削除
  • "$ref"の使用を、スキーマが期待される場所に限定
  • "JSON Schemaデータモデル"の定義を追加
  • 追加のセキュリティに関する考慮事項を追加
  • "id"のサブスキーマ識別子の使用を定義
  • HTTPでの使用に関するセクションを書き換え
  • rel="describedBy"とrel="profile"での使用に関するセクションを書き換え
  • 多数の無効な例を修正
draft-zyp-json-schema-04
  • ドラフトv3からサルベージされました。
  • 検証キーワードを別のドキュメントに分割しました。
  • ハイパーメディアキーワードを別のドキュメントに分割しました。
  • 分割後の最初のドラフト。
  • JSON参照、JSONポインタの使用を義務付けました。
  • "id"の役割を定義しました。URI解決スコープを定義しました。
  • 相互運用性の考慮事項を追加しました。
draft-zyp-json-schema-00
  • 最初のドラフト。

著者アドレス

Austin Wright(編集者
Henry Andrews(編集者
Ben Hutton(編集者
ポストマン
Greg Dennis