インターネットドラフト | JSON Schema | 2022年6月 |
Wright, et al. | 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.dokyumento.jp/を参照してください。¶
フィードバックを提供するには、この課題追跡ツール、ホームページに記載されているコミュニケーション方法、またはドキュメント編集者にメールでご連絡ください。¶
このインターネットドラフトは、BCP 78およびBCP 79の規定に完全に準拠して提出されています。¶
インターネットドラフトは、インターネットエンジニアリングタスクフォース(IETF)のワーキングドキュメントです。他のグループも、ワーキングドキュメントをインターネットドラフトとして配布する場合があることに注意してください。現在のインターネットドラフトのリストは、https://datatracker.ietf.org/drafts/current/にあります。¶
インターネットドラフトは、最大6か月間有効なドラフトドキュメントであり、いつでも他のドキュメントによって更新、置き換え、または廃止される可能性があります。インターネットドラフトを参照資料として使用したり、「作業中」として以外に引用したりすることは不適切です。¶
このインターネットドラフトは、2022年12月18日に失効します。¶
著作権(c)2022 IETF Trustおよびドキュメントの作成者として特定された人物。全著作権所有。¶
このドキュメントは、BCP 78およびこのドキュメントの発行日に有効なIETF TrustのIETFドキュメントに関する法的規定(https://trustee.ietf.org/license-info)の対象となります。このドキュメントに関するあなたの権利と制限を説明しているため、これらのドキュメントを注意深く確認してください。このドキュメントから抽出されたコードコンポーネントには、トラストの法的規定のセクション4.eに記載されている改訂BSDライセンスのテキストを含める必要があり、改訂BSDライセンスに記載されているように保証なしで提供されます。¶
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" メディアタイプの機能に不可欠であり、他の語彙の読み込みをブートストラップするために使用されます。¶
さらに、このドキュメントでは、サブスキーマを条件付きで適用するため、およびオブジェクトと配列の内容にサブスキーマを適用するためのキーワードの推奨語彙を定義します。この語彙または非常によく似た語彙は、アサーション検証、アノテーション、またはその両方を目的としているかどうかにかかわらず、非自明なJSONインスタンスのスキーマを作成するために必要です。必須のコア語彙の一部ではありませんが、最大限の相互運用性を実現するために、この追加語彙はこのドキュメントに含まれており、その使用が強く推奨されます。¶
構造検証やハイパーメディアアノテーションなどの目的のための追加の語彙は、他のドキュメントで定義されています。これらの他のドキュメントはそれぞれ、そのドキュメントの目的にスキーマを記述するために必要な標準的な語彙セットを収集するダイアレクトを定義します。¶
JSONドキュメントは、application/jsonメディアタイプによって記述される情報リソース(オクテットの連続)です。¶
JSON Schemaでは、データモデルを定義するため、「JSONドキュメント」、「JSONテキスト」、および「JSON値」という用語は互換性があります。¶
JSON Schemaは、JSONドキュメントでのみ定義されます。ただし、JSON Schemaデータモデルに従って解析または処理できるドキュメントまたはメモリー構造は、CBOR [RFC7049]などのメディアタイプを含め、JSON Schemaに対して解釈できます。¶
スキーマが適用されるJSONドキュメントは、「インスタンス」と呼ばれます。¶
JSON Schemaは、"+json"構造化構文サフィックスを持つメディアタイプを含む、"application/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データモデルのスーパーセットで使用でき、インスタンスは6つのJSONデータ型のいずれにも属さない場合があります。¶
この場合、アノテーションは引き続き適用されますが、ほとんどの検証キーワードは常に成功または常に失敗するため、有用ではありません。¶
カスタム語彙は、コアデータモデルのスーパーセットのサポートを定義できます。スキーマ自体は、このスーパーセットでのみ表現可能である場合があります。たとえば、"const"キーワードを使用する場合などです。¶
JSONスキーマドキュメント、または単にスキーマとは、インスタンスを記述するために使用されるJSONドキュメントのことです。スキーマ自体をインスタンスとして解釈することもできますが、"application/schema-instance+json"ではなく、常に"application/schema+json"のメディアタイプを指定する必要があります。"application/schema+json"メディアタイプは、"application/schema-instance+json"によって提供されるフラグメント識別子の構文とセマンティクスのスーパーセットを提供するために定義されています。¶
JSONスキーマは、オブジェクトまたはブール値である必要があります。¶
インスタンスに適用されるオブジェクトのプロパティは、キーワード、またはスキーマキーワードと呼ばれます。大まかに言って、キーワードは次の5つのカテゴリに分類されます。¶
キーワードは複数のカテゴリに分類される場合がありますが、アプリケータはサブスキーマの結果に基づいてのみアサーション結果を生成する必要があります。サブスキーマとは独立した追加の制約を定義しないでください。¶
同じスキーマオブジェクト内のプロパティであるキーワードは、隣接キーワードと呼ばれます。¶
拡張キーワード(このドキュメントとその付随ドキュメント以外で定義されているもの)は、他の動作を自由に定義できます。¶
JSONスキーマには、スキーマキーワードではないプロパティが含まれている場合があります。不明なキーワードはアノテーションとして扱われる必要があり、キーワードの値はアノテーションの値になります。¶
空のスキーマとは、プロパティがない、または不明なプロパティのみを持つJSONスキーマのことです。¶
ブール値のスキーマ値である "true" と "false" は、インスタンスの値に関係なく、常に自身をアサーション結果として生成する単純なスキーマです。アノテーション結果を生成することはありません。¶
これらのブールスキーマは、スキーマ作成者の意図を明確にし、スキーマ処理の最適化を促進するために存在します。これらは、次のスキーマオブジェクト(ここで "not" はこのドキュメントで定義されているサブスキーマアプリケーション語彙の一部です)と同じように動作します。¶
空のスキーマオブジェクトは曖昧ではありませんが、"false" スキーマには多くの同等のものが考えられます。ブール値を使用することで、意図が人間と実装の両方に明確に伝わるようになります。¶
スキーマ語彙、または単に語彙とは、キーワード、その構文、およびセマンティクスのセットのことです。語彙は通常、特定の目的を中心に構成されます。検証、ハイパーメディア、ユーザーインターフェースの生成など、JSONスキーマのさまざまな用途には、さまざまな語彙セットが関連します。¶
語彙は、スキーマ作成者がスキーマを処理するために必要な語彙またはオプションの語彙を示すことができるため、JSONスキーマにおける再利用の主要な単位です。語彙はメタスキーマでURIによって識別されるため、一般的な実装では、以前に不明だった語彙をサポートする拡張機能をロードできます。キーワードは語彙の外部でサポートできますが、個々のキーワードの使用を示す同様のメカニズムはありません。¶
スキーマ語彙は、対象者と相互運用性の期待に応じて、非公式な説明から標準提案まで、さまざまなもので定義できます。特に、非公開組織内での語彙の使用を容易にするために、語彙仕様をその使用範囲外で公開する必要はありません。¶
スキーマ自体を記述するスキーマは、メタスキーマと呼ばれます。メタスキーマは、JSONスキーマを検証し、使用している語彙を指定するために使用されます。¶
通常、メタスキーマは語彙のセットを指定し、それらの語彙の構文に準拠したスキーマを検証します。ただし、メタスキーマが語彙の仕様で要求されているよりも厳密または緩やかにスキーマの準拠を検証できるように、メタスキーマと語彙は分離されています。メタスキーマは、正式な語彙の一部ではない追加のキーワードを記述および検証することもできます。¶
JSONスキーマのリソースとは、正規の [RFC6596] 絶対URI [RFC3986]によって識別されるスキーマのことです。スキーマのリソースは、結果として得られる二次リソース(RFC 3986のセクション3.5 [RFC3986]で定義)がプライマリリソースと同じである場合、フラグメントを含むURIを含む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スキーマドキュメントに抽出された場合もドキュメントルートスキーマになります。¶
複数のスキーマのリソースが埋め込まれているか、参照でリンクされているかにかかわらず、それらは同じ方法で処理され、同じ利用可能な動作が行われます。¶
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)のセクションで指定されています。¶
インスタンスは、JSON [RFC8259]で定義されているように、有効なJSON値である場合があります。JSONスキーマは型に制限を課しません。JSONスキーマは、たとえばnullを含む任意のJSON値を記述できます。¶
JSONスキーマはプログラミング言語に依存せず、データモデルで記述されている値の全範囲をサポートします。ただし、一部の言語やJSONパーサーは、JSONで記述可能な値の全範囲をメモリ内で表現できない場合があることに注意してください。¶
一部のプログラミング言語とパーサーは、浮動小数点数の内部表現と整数の内部表現を異なる方法で使用します。¶
一貫性のために、整数のJSON数値は小数部なしでエンコードする必要があります。¶
キーワードは、制約を表現したり、インスタンス値を正規表現に制約したりするために、正規表現を使用する場合があります。これらの正規表現は、ECMA-262、セクション21.2.1 [ecma262]で説明されている正規表現の方言に従って有効である必要があります。¶
正規表現は、Unicodeサポートを提供するために「u」フラグ(または同等のもの)を使用して作成するか、ECMA-262で定義されているUnicodeサポートを提供するような方法で処理する必要があります。¶
さらに、正規表現の構文サポートには大きなばらつきがあるため、スキーマの作成者は、以下の正規表現トークンに限定する必要があります。¶
最後に、実装は正規表現を、先頭にも末尾にも固定されているとみなしてはなりません。たとえば、パターン "es" は "expression" に一致します。¶
追加のスキーマキーワードとスキーマ語彙は、任意のエンティティによって定義できます。明示的な合意がない限り、スキーマの作成者は、そのようなサポートを明示的に文書化していない実装がこれらの追加キーワードと語彙をサポートすることを期待してはなりません。実装は、サポートしていないキーワードを注釈として扱い、キーワードの値が注釈の値であるべきです。¶
実装は、直接サポートしていない語彙のハンドラーを登録またはロードする機能を提供できます。このようなハンドラーを登録および実装するための正確なメカニズムは、実装に依存します。¶
JSONスキーマのキーワードは、いくつかの一般的な動作カテゴリに分類されます。アサーションは、インスタンスが制約を満たしていることを検証し、ブール値を生成します。注釈は、アプリケーションが適切と判断する方法で使用できる情報を添付します。アプリケーターは、インスタンスの一部にサブスキーマを適用し、その結果を結合します。¶
拡張キーワードは、特に注釈が非常に柔軟であることを念頭に置いて、これらのカテゴリ内に留まる必要があります。複雑な動作は通常、スキーマキーワードとして直接実装するよりも、注釈データに基づいてアプリケーションに委任する方が適切です。ただし、拡張キーワードは、特殊な目的のために他の動作を定義してもかまいません。¶
スキーマに対するインスタンスの評価には、インスタンス内の適切な場所に対して、スキーマ内のすべてのキーワードを処理することが含まれます。通常、アプリケーターキーワードは、アプリケーター(したがってサブスキーマがない)を持たないスキーマオブジェクトに到達するまで処理されます。インスタンス内の適切な場所は、スキーマオブジェクト内のアサーションおよび注釈キーワードに対して評価され、それらの結果は、アプリケーターのルールに従って親スキーマに収集されます。¶
親スキーマオブジェクトの評価は、そのすべてのサブスキーマが評価された後に完了できますが、状況によっては、アサーションの結果により評価が途中で打ち切られる場合があります。注釈を収集する場合、アサーションの結果をさらに変更できないサブスキーマを含め、すべてのサブスキーマを調べる必要があるため、アサーション結果の途中で打ち切ることはできません。¶
ほとんどのJSONスキーマキーワードは単独で評価できますが、多くても同じスキーマオブジェクト内の隣接するキーワードの値または結果を考慮する必要があるだけですが、一部はより複雑な動作をします。¶
キーワードの字句スコープは、オブジェクトと配列のネストされたJSONデータ構造によって決定されます。最大のそのようなスコープは、スキーマドキュメント全体です。最小のスコープは、サブスキーマのない単一のスキーマオブジェクトです。¶
キーワードは、URI参照など、部分的な値で定義できます。これは、JSONドキュメントの字句構造を介して見つかった別のURI参照または完全なURIなど、別の値に対して解決する必要があります。「$id」、「$ref」、および「$dynamicRef」のコアキーワード、および「base」JSONハイパースキーマキーワードは、この種の動作の例です。¶
「$schema」などの一部のキーワードは、スキーマリソース全体の字句スコープに適用されるため、スキーマリソースのルートスキーマにのみ出現する必要があることに注意してください。¶
他のキーワードは、通常、インスタンスドキュメントとともに、スキーマの評価中に存在する動的スコープを考慮に入れる場合があります。最も外側の動的スコープは、スキーマリソースのルートでなくても、処理が開始されるスキーマオブジェクトです。このルートスキーマから特定のキーワード(解決された可能性のある「$ref」および「$dynamicRef」キーワードを含む)へのパスは、キーワードの「検証パス」と見なされます。¶
参照キーワードに遭遇するまで、字句スコープと動的スコープは一致します。参照キーワードをたどると、処理は1つの字句スコープから別の字句スコープに移動しますが、動的スコープの観点から見ると、参照をたどることは、値として存在するサブスキーマに下降することと変わりません。動的スコープを介して情報を解決する参照の反対側にあるキーワードは、局所的に字句的に囲む親を調べるのではなく、参照の元の側を動的親と見なします。¶
動的スコープの概念は、主に「$dynamicRef」と「$dynamicAnchor」で使用され、高度な機能と見なされ、追加のキーワードを定義する際には注意して使用する必要があります。エラーと収集された注釈を報告する場合にも表示されます。これは、異なる動的スコープで同じ字句スコープを繰り返し再訪できる場合があるためです。このような場合、エラーまたは注釈を生成した動的パスをユーザーに通知することが重要です。¶
キーワードの動作は、サブスキーマ (セクション4.3.5)および/または隣接するキーワード(同じスキーマオブジェクト内のキーワード)とそのサブスキーマの注釈の結果に関して定義できます。このようなキーワードは、循環依存関係を生じさせてはなりません。キーワードは、同じスキーマオブジェクト (セクション4.3)内の別のキーワードの有無に基づいて動作を変更できます。¶
欠落しているキーワードは、falseのアサーション結果を生成してはならず、注釈の結果を生成してはならず、独自の動作定義の一部として他のスキーマを評価させてはなりません。ただし、欠落しているキーワードは注釈を提供しないため、注釈の結果がないと、他のキーワードの動作が間接的に変更される可能性があります。¶
場合によっては、キーワードの欠落したキーワードアサーションの動作は、特定の値によって生成される動作と同じであり、キーワードの定義では、既知の値を記録する必要があります。ただし、デフォルトの動作を生成する値が存在する場合に注釈の結果を生成する場合でも、デフォルトの動作は注釈を生成してはなりません。¶
注釈の収集は、計算とメモリの両方の点で大きなコストを追加する可能性があるため、実装はこの機能をオプトアウトできます。収集された注釈に関して指定されているキーワードは、適切な場合は、適切な代替アプローチを説明する必要があります。このアプローチは、このドキュメントの「items」および「additionalProperties」キーワードによって示されています。¶
このような代替アプローチがキーワードに対して不可能な場合、注釈の収集をサポートしない実装は、それらを含むキーワードまたは語彙をサポートできないことに注意してください。¶
識別子は、スキーマのURIを定義するか、参照 (セクション8.2.3)でそのようなURIがどのように解決されるかに影響を与えるか、またはその両方に影響を与えます。このドキュメントで定義されているコア語彙は、いくつかの識別キーワード(特に「$id」)を定義しています。¶
正規スキーマURIは、インスタンスの処理中に変更してはなりませんが、URI参照の解決に影響を与えるキーワードは、実行時に完全に決定される動作を持つ場合があります。¶
カスタム識別子キーワードは可能ですが、語彙の設計者はコアキーワードの機能を中断しないように注意する必要があります。たとえば、この仕様の「$dynamicAnchor」キーワードは、URI解決の影響を一致する「$dynamicRef」キーワードに限定し、「$ref」の動作を変更しません。¶
アプリケーターを使用すると、単一のスキーマオブジェクトで実現できるよりも複雑なスキーマを構築できます。スキーマドキュメント (セクション4.3)に対するインスタンスの評価は、ルートスキーマ (セクション4.3.5)を完全なインスタンスドキュメントに適用することによって開始されます。そこから、アプリケーターとして知られるキーワードを使用して、どの追加のスキーマを適用するかを決定します。このようなスキーマは、現在の場所にインプレースで適用することも、子ロケーションに適用することもできます。¶
適用するスキーマは、キーワードの値の全部または一部を構成するサブスキーマとして存在する場合があります。または、アプリケーターは、同じスキーマドキュメントまたは別のドキュメント内の別の場所にあるスキーマを参照する場合があります。そのような参照スキーマを識別するメカニズムは、キーワードによって定義されます。¶
アプリケーターキーワードは、サブスキーマまたは参照スキーマのブール値アサーション (セクション7.6)の結果が、アプリケーターのブール値の結果を生成するためにどのように変更および/または結合されるかも定義します。アプリケーターは、サブスキーマのアサーション結果に任意のブール論理演算を適用できますが、独自のアサーション条件を導入してはなりません。¶
注釈 (セクション7.7)の結果は、インスタンスの場所とスキーマキーワードの場所とともに保持されるため、アプリケーションは複数の値をどのように解釈するかを決定できます。¶
セクション7.5で説明したように、アプリケーターキーワードは、アプリケーターの値にサブスキーマとして含めるのではなく、適用されるスキーマを参照する場合があります。このような状況では、適用されるスキーマは参照スキーマとして知られ、アプリケーターキーワードを含むスキーマは参照するスキーマです。¶
ルートスキーマとサブスキーマは、スキーマドキュメント内のスキーマの位置に基づく静的な概念ですが、参照スキーマと参照するスキーマは動的です。インスタンスがスキーマに対して評価される間に、さまざまなスキーマのペアがさまざまな参照および参照の配置になる可能性があります。¶
"$ref" (セクション8.2.3.1)など、一部の参照によるアプリケーターの場合、参照スキーマはスキーマドキュメントの字句スコープの静的分析によって決定できます。(「$dynamicAnchor」付きの)「$dynamicRef」など、動的スコープを利用する可能性があり、インスタンスを使用したスキーマの評価プロセスでのみ解決できる可能性があります。¶
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は、インスタンスがアノテーションを含むスキーマオブジェクト、およびそのすべての親スキーマオブジェクトに対して検証されるたびに、インスタンスに情報をアノテーションとして付与できます。情報は単純な値である場合もあれば、インスタンスの内容に基づいて計算される場合もあります。¶
アノテーションは、インスタンス内の特定の場所に付与されます。多くのサブスキーマを単一の場所に適用できるため、アプリケーションは、異なるスキーマオブジェクト内の同じスキーマキーワードによって、同じインスタンスの場所に付与された異なるアノテーション値をどのように処理するかを決定する必要がある場合があります。¶
アサーションの結果とは異なり、アノテーションデータはさまざまな形式をとることができ、アプリケーションが適切と判断したとおりに使用できます。JSON Schemaの実装は、アプリケーションに代わって収集された情報を使用することは期待されていません。¶
特に指定がない限り、アノテーションキーワードの値はキーワードの値です。ただし、他の動作も可能です。たとえば、JSON Hyper-Schema [json-hyper-schema]の "links" キーワードは、インスタンスデータの一部に基づいて値を生成する複雑なアノテーションです。¶
アサーションでは「ショートサーキット」評価が可能ですが、アノテーションを収集するには、全体的なアサーションの結果を変更できない場合でも、インスタンスの場所に適用されるすべてのスキーマを調べる必要があります。唯一の例外は、検証に失敗したスキーマオブジェクトのサブスキーマは、アノテーションが失敗したスキーマには保持されないため、スキップできるということです。¶
アノテーションは、アノテーション収集動作を明示的に定義するキーワードによって収集されます。ブール値スキーマはキーワードを使用しないため、アノテーションを生成できないことに注意してください。¶
収集されたアノテーションには、次の情報が含まれている必要があります。¶
アプリケーションは、値を提供したスキーマの場所に基づいて、使用する複数のアノテーション値のどれを使用するかを決定できます。これは、柔軟な使用を可能にすることを目的としています。スキーマの場所を収集すると、このような使用が容易になります。¶
たとえば、次のスキーマを考えてみましょう。これは、検証仕様 [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つの異なる値が存在することをエラーと見なす場合があります。¶
falseのアサーション結果を生成するスキーマオブジェクトは、独自のキーワードまたはサブスキーマ内のキーワードからアノテーション結果を生成してはなりません。¶
ただし、スキーマ全体の評価結果には、他のスキーマの場所から収集されたアノテーションが含まれる場合があります。次のスキーマの場合:¶
{ "oneOf": [ { "title": "Integer Value", "type": "integer" }, { "title": "String Value", "type": "string" } ] }¶
インスタンス"これは文字列です"
に対して、そのスキーマオブジェクトの型アサーションが失敗するため、タイトルアノテーション "整数値" は破棄されます。インスタンスが文字列型のアサーションに合格するため、タイトルアノテーション "文字列値" は保持されます。¶
アプリケーターキーワードは、独自のアノテーション結果を定義する可能性に加えて、サブスキーマまたは参照スキーマで収集されたアノテーションを集約します。¶
4番目のキーワードのカテゴリは、再利用に適さない、スキーマ作成者にとって関心のある再利用可能なコンポーネントまたはデータを保持するための場所を予約するだけです。これらのキーワードは、検証結果やアノテーション結果に影響を与えません。コア語彙での目的は、特定の目的のために場所が利用可能であり、拡張キーワードによって再定義されないようにすることです。¶
これらのキーワードは直接結果に影響を与えませんが、9.4.2で説明したように、再利用可能なスキーマの場所を予約する認識されない拡張キーワードは、特定の状況で参照と望ましくない相互作用を起こす可能性があります。¶
このドキュメントまたは関連ドキュメントの一部として定義されている語彙のいずれにも、インスタンスデータをターゲットにしたりロードしたりする可能性のあるキーワードは定義されていませんが、他の語彙がそうすることを望む可能性があります。¶
キーワードは、JSONポインターまたは相対JSONポインターを使用して、現在の評価の場所の外側のインスタンスの一部を調べることができます。¶
相対JSONポインターを使用して場所を調整できるキーワードは、デフォルトが望ましい場合は、現在の場所をデフォルトで使用する必要があります。¶
このセクションで宣言されている、すべて "$" で始まるキーワードは、JSON Schemaコア語彙を構成します。これらのキーワードは、複数のドキュメントに分割されているものを含め、任意のスキーマまたはメタスキーマを処理するために必須であるか、保証された相互運用性を必要とする目的のためにキーワードを予約するために存在します。¶
コア語彙は、他の語彙の処理をブートストラップするために、常に必須と見なす必要があります。使用する語彙を宣言するために"$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。¶
コア語彙に対して "$" プレフィックスが正式に予約されているわけではありませんが、拡張キーワード(語彙内またはその他の場合)は、将来の衝突の可能性を回避するために "$" 以外の文字で開始することを推奨します。¶
メタスキーマと語彙の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'が宣言した語彙をバリデーターが理解する必要なく、独自のメタスキーマに対して検証することができます。¶
"$vocabulary" がない場合、実装は、参照スキーマの "$schema" キーワードのURI値から認識される場合は、メタスキーマに基づいて動作を決定してもよいです。これは、語彙の存在に先立って、(Hyper-Schemaの使用などの)動作が認識されていた方法です。¶
スキーマによって参照されるメタスキーマが認識されない場合、または欠落している場合、動作は実装定義です。実装がスキーマの処理を続行する場合、コア語彙の使用を想定する必要があります。実装が特定の目的のために構築されている場合は、その目的に最も関連性の高いすべての語彙の使用を想定する必要があります。¶
たとえば、バリデーターである実装は、この仕様と付随する検証仕様のすべての語彙の使用を想定する必要があります。¶
"$vocabulary" の処理制限は、"$ref" または同様のキーワードを使用して他のメタスキーマを参照するメタスキーマが、それらの他のメタスキーマの語彙宣言を自動的に継承しないことを意味することに注意してください。このような宣言はすべて、メタスキーマとして使用することを意図した各スキーマドキュメントのルートで繰り返す必要があります。これは、メタスキーマの例 (付録 D.2) で示されています。この要件により、実装は各メタスキーマの1か所ですべての語彙要件情報を見つけることができます。スキーマの拡張性により、より細かく粒度の細かいメタスキーマをリファレンスで組み合わせる潜在的な方法は無限にあるため、実装にすべての可能性を予測し、参照されるメタスキーマで語彙を検索させることは、過度に負担になります。¶
エラーを修正するために、仕様ドラフト間で更新された語彙とメタスキーマURIが公開される可能性があります。実装は、この仕様ドラフト以降で次の仕様ドラフトより前の日付のURIを、ここにリストされているものと同じ構文およびセマンティクスを示すものと見なす必要があります。¶
膨大なエコシステム内のスキーマを区別するために、スキーマはURI [RFC3986]で識別され、URIを指定することで他のスキーマへの参照を埋め込むことができます。¶
いくつかのキーワードは、相対的なURI-参照 [RFC3986]、または相対URI参照を作成するために使用される値を受け入れることができます。これらのキーワードの場合、参照を解決するためにベースURIを確立する必要があります。¶
"$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に関するRFC 3986セクション5.1.1 [RFC3986]に従って、スキーマリソース内のキーワードの相対URI参照のベースURIとしても機能します。¶
サブスキーマに "$id" が存在することは、サブスキーマが単一のスキーマドキュメント内で個別のスキーマリソースを構成することを示します。さらに、エンティティのカプセル化に関するRFC 3986セクション5.1.2 [RFC3986]に従って、サブスキーマの "$id" が相対URI参照である場合、その参照を解決するためのベースURIは、親スキーマリソースのURIです。¶
親スキーマオブジェクトが"$id"でリソースとして明示的に識別しない場合、ベースURIは、前のセクションで示された手順によって確立された、ドキュメント全体のベースURIです。(セクション9.1.1)¶
JSONスキーマドキュメントのルートスキーマには、絶対URI [RFC3986](スキームを含み、フラグメントを含まない)を含む "$id" キーワードが含まれている必要があります。¶
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」の任意の組み合わせを使用して、同じフラグメント名を複数回指定した場合の効果は未定義です。このような使用が検出された場合、実装はエラーを発生させる可能性があります。¶
現在のインスタンスの場所に適用されるスキーマを参照するために、いくつかのキーワードを使用できます。「$ref」および「$dynamicRef」は、参照されるスキーマをインスタンスに適用するアプリケーターキーワードです。¶
「$ref」および「$dynamicRef」の値はURI参照であるため、スキーマを複数のファイルに外部化または分割することが可能になり、自己参照による再帰構造を検証する機能が提供されます。¶
これらのキーワードによって生成される解決済みURIは、必ずしもネットワークロケーターではなく、単なる識別子です。スキーマは、ネットワークアドレス可能なURLである場合でも、そのアドレスからダウンロード可能である必要はなく、実装は、ネットワークアドレス可能なURIに遭遇したときにネットワーク操作を実行する必要があると想定すべきではありません。¶
「$ref」キーワードは、静的に識別されたスキーマを参照するために使用されるアプリケーターです。その結果は、参照されるスキーマの結果です。結果がどのように決定されるかというこの定義は、「$ref」と同じスキーマオブジェクトに他のキーワードが表示される可能性があることを意味することに注意してください。¶
「$ref」キーワードの値は、URI参照である文字列でなければなりません。現在のURIベースに対して解決すると、適用するスキーマのURIが生成されます。インスタンスを評価するプロセスによって参照がどのように解決されるかが変わることはないため、この解決はスキーマのロード時に安全に実行できます。¶
「$dynamicRef」キーワードは、実行時まで完全な解決を遅らせることができるアプリケーターであり、実行時にインスタンスを評価する際に遭遇するたびに解決されます。¶
「$dynamicAnchor」と共に、「$dynamicRef」は、主に再帰的スキーマ(それ自体を参照するスキーマ)で役立つ協調拡張メカニズムを実装します。拡張ポイントとランタイムで決定される拡張ターゲットはどちらも「$dynamicAnchor」で定義され、「$dynamicRef」で参照された場合にのみランタイムの動的動作を示します。¶
「$dynamicRef」プロパティの値は、URI参照である文字列でなければなりません。現在のURIベースに対して解決すると、ランタイム解決の開始点として使用されるURIが生成されます。この初期解決は、スキーマのロード時に安全に実行できます。¶
最初に解決された開始点URIに、「$dynamicAnchor」キーワードによって作成されたフラグメントが含まれている場合、初期URIは、「$dynamicAnchor」を使用して同じ名前のフラグメントを定義する動的スコープ (セクション 7.1)の最外スキーマリソースのURI(フラグメントを含む)で置き換える必要があります。¶
それ以外の場合、その動作は「$ref」と同じであり、ランタイム解決は必要ありません。¶
これらのキーワードを使用した完全な例については、付録Cを参照してください。2019年以前のドラフトのハイパースキーマメタスキーマとこのドラフトの違いは、これらのキーワードの有用性を劇的に示しています。¶
「$defs」キーワードは、スキーマ作成者が再利用可能なJSONスキーマをより一般的なスキーマにインライン化するための場所を予約します。このキーワードは、検証結果に直接影響しません。¶
このキーワードの値はオブジェクトでなければなりません。このオブジェクトの各メンバーの値は、有効なJSONスキーマでなければなりません。¶
例として、次に正の整数の配列を記述するスキーマを示します。ここで、正の整数の制約は「$defs」のサブスキーマです。¶
{ "type": "array", "items": { "$ref": "#/$defs/positiveInteger" }, "$defs": { "positiveInteger": { "type": "integer", "exclusiveMinimum": 0 } } }¶
このキーワードは、スキーマ作成者からスキーマの読者または保守者へのコメントのための場所を予約します。¶
このキーワードの値は文字列でなければなりません。実装は、この文字列をエンドユーザーに提示してはなりません。スキーマを編集するためのツールは、このキーワードの表示と編集をサポートする必要があります。このキーワードの値は、スキーマを使用する開発者を対象としたデバッグまたはエラー出力で使用できます。¶
スキーマ語彙は、語彙キーワードを含む任意のオブジェクト内で「$comment」を許可する必要があります。実装は、語彙が明示的に禁止しない限り、「$comment」が許可されていると想定できます。語彙は、この仕様で説明されている範囲を超えて「$comment」の効果を指定してはなりません。¶
他のメディアタイプまたはプログラミング言語をapplication/schema+jsonとの間で変換するツールは、そのメディアタイプまたはプログラミング言語のネイティブコメントを「$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を文書化することを推奨します。¶
スキーマオブジェクトが別のメディアタイプのドキュメントに埋め込まれている場合、初期ベースURIはそのメディアタイプのルールに従って決定されます。¶
前のセクションで説明した「$id」キーワードがルートスキーマに存在しない限り、このベースURIはスキーマドキュメントのルートスキーマリソースの正規URIと見なす必要があります。¶
リモートスキーマを識別するためのURIの使用は、必ずしも何かがダウンロードされることを意味するのではなく、JSONスキーマの実装は、どのスキーマを使用するか、およびそれらを識別するURIを事前に理解する必要があります。¶
たとえば、実行時までダウンロードするスキーマを認識しない汎用ユーザーエージェントによってスキーマがダウンロードされる場合は、ハイパーメディアの使用 (セクション 9.5.1)を参照してください。¶
実装は、バリデーターがスキーマに対して持つ信頼度に応じて、任意のURIを任意のスキーマに関連付けたり、スキーマの"$id"で指定されたURIを自動的に関連付けたりできる必要があります(SHOULD)。そのようなURIとスキーマは、インスタンスを処理する前に実装に提供したり、処理中にスキーマドキュメント内に記述したりでき、付録Aに示すような関連付けを生成します。¶
スキーマは複数のURIを持つ可能性があります(そしておそらく持つでしょう)が、1つのURIが複数のスキーマを識別する方法はありません。複数のスキーマが同じURIとして識別を試みる場合、バリデーターはエラー状態を発生させる必要があります(SHOULD)。¶
実装は、別のスキーマの "$schema" キーワードによってメタスキーマとして識別されたために検査されている場合、スキーマをメタスキーマとして認識する必要があります(MUST)。これは、単一のスキーマドキュメントが、ある時は通常のスキーマと見なされ、別の時にはメタスキーマと見なされる可能性があることを意味します。¶
自身のメタスキーマであるスキーマを検査する場合、実装がそれを通常のスキーマとして処理し始めるときは、それらのルールに基づいて処理されます。ただし、自身の "$schema" 値をチェックした結果として2回目にロードされるときは、メタスキーマとして扱われます。したがって、同じドキュメントが1つのセッション中に両方の方法で処理されます。¶
実装は、実装固有の目的(例えば、一般的に使用されるメタスキーマのプリロードや、その語彙サポート要件の事前チェックなど)のために、スキーマを明示的にメタスキーマとして渡すことを許可できます(MAY)。メタスキーマの作成者は、そのような機能が実装間で相互運用可能であるとは期待すべきではありません(MUST NOT)。¶
スキーマは、JSONポインターや "$id" で直接指定されたURIを含む、付与された任意のURIで識別できます。すべての場合において、"$ref" 参照を逆参照するには、まずその値を、RFC 3986 [RFC3986]に従って現在のベースURIに対するURI参照として解決する必要があります。¶
結果のURIが現在のドキュメント内、または実装で利用可能になっている別のスキーマドキュメント内のスキーマを識別する場合、そのスキーマは自動的に使用される必要があります(SHOULD)。¶
たとえば、次のスキーマを考えてみましょう。¶
{ "$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の場合、新しいスキーマがシステムに動的に追加されることが予想されるため、スキーマドキュメントのプリロードを絶対的に要求することは現実的ではありません。¶
JSONポインターURIフラグメントはスキーマドキュメントの構造に基づいて構築されるため、埋め込みスキーマリソースとそのサブスキーマは、それ自体の正規URI、または包含リソースのURIに対する相対的なJSONポインターフラグメントで識別できます。¶
概念的には、リンクされたスキーマリソースのセットは、各リソースがスキーマ参照 (セクション8.2.3)で接続された個別のドキュメントであるか、1つ以上のスキーマリソースがサブスキーマとして埋め込まれた単一のドキュメントとして構造化されているかに関わらず、同じように動作する必要があります。¶
親スキーマリソースのURIに対する相対的なJSONポインターフラグメントを含むURIは、埋め込みスキーマが別のドキュメントに移動されて参照されると無効になるため、アプリケーションとスキーマは、そのようなURIを埋め込みスキーマリソースまたはその中の場所を識別するために使用すべきではありません(SHOULD NOT)。¶
別のスキーマリソースが埋め込まれている次のスキーマドキュメントを考えてみましょう。¶
{ "$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によるスキーマリソースコンテンツのアドレス指定をサポートしないことを選択できます(MAY)。したがって、スキーマ作成者はそのようなURIに依存すべきではありません(SHOULD NOT)。それらを使用すると、相互運用性が低下する可能性があるためです。これは、スキーマリソースが再編成された場合に壊れやすいものを除いて、すべてに対して、考えられるベース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に記載されています。¶
複合スキーマドキュメントは、転送を容易にするために複数の埋め込みJSONスキーマリソースが同じドキュメントにバンドルされているJSONドキュメント(「バンドル」スキーマとも呼ばれる)として定義されます。¶
各埋め込みスキーマリソースは、語彙サポートの決定など、標準のスキーマロードおよび処理要件に従い、個別のスキーマリソースとして扱われる必要があります(MUST)。¶
複合スキーマドキュメントを作成するためのバンドルプロセスは、外部スキーマリソースへの参照("$ref"など)を取得し、参照先のスキーマリソースを参照側のドキュメント内に埋め込むこととして定義されます。バンドルは、ベースドキュメントと参照/埋め込みドキュメントのすべてのURI(参照に使用される)を変更する必要がないように行う必要があります(SHOULD)。¶
各埋め込み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またはパスが含まれます。¶
バンドルプロセスは多くの場合、複合スキーマドキュメントを作成する主な方法になりますが、以前は個々のスキーマリソースが存在していなかった可能性のある手作業で作成されることも予想されます。¶
複数のスキーマリソースが1つのドキュメントに存在する場合、処理すべき方言を定義しないスキーマリソースは、囲んでいるリソースと同じ方言で処理する必要があります(MUST)。¶
参照できるスキーマは埋め込むこともできるため、埋め込まれたスキーマリソースは、囲んでいるリソースからの "$schema" 値を使用して、異なる処理方言を指定できます(MAY)。¶
複合スキーマドキュメントには、異なる方言を使用すると識別される埋め込みリソースが含まれる可能性があるため、これらのドキュメントは、メタスキーマをインスタンスとして複合スキーマドキュメントに適用して検証すべきではありません(SHOULD NOT)。スキーマドキュメントを検証するために、代替の検証プロセスを提供することを推奨します(RECOMMENDED)。各スキーマリソースは、関連付けられたメタスキーマに対して個別に検証する必要があります(SHOULD)。検証されているのがスキーマであることがわかっている場合は、ドキュメントのルートで使用されていない場合に埋め込みリソースを識別する"$id"を使用することで、スキーマが複合スキーマドキュメントであるかどうかを識別できます。¶
すべての埋め込みリソースが同じ方言を使用すると識別するか、"$schema" が省略されて囲んでいるリソースのデフォルトになっている複合スキーマドキュメントは、適切なメタスキーマを適用して検証できます(MAY)。¶
スキーマは、インスタンスに対して無限ループに陥ってはなりません。例えば、2つのスキーマ "#alice" と "#bob" が両方とも、お互いを参照する "allOf" プロパティを持っている場合、ナイーブなバリデーターはインスタンスを検証しようとして無限再帰ループに陥る可能性があります。スキーマはこのように無限再帰的なネストを使用するべきではありません。動作は未定義です。¶
サブスキーマオブジェクト(またはブール値)は、既知のアプリケーターキーワード、または1つ以上のサブスキーマを値として取る"$defs" (8.2.4節)などのロケーション予約キーワードとの使用によって認識されます。これらのキーワードは、"$defs" およびこのドキュメントの標準アプリケーター、既知の語彙からの拡張キーワード、または実装固有のカスタムキーワードである可能性があります。¶
未知のキーワードの多層構造は、ネストされたサブスキーマを導入する可能性があり、それは"$id"の処理規則に従うことになります。したがって、そのような認識されない構造内の参照ターゲットは、確実に実装することができず、結果として得られる動作は未定義です。同様に、既知のキーワードの下の参照ターゲットで、その値がスキーマではないことがわかっている場合は、実装にそのようなターゲットを検出する必要性を課すことを避けるために、未定義の動作になります。 これらのシナリオは、HTTP経由でスキーマを取得したが、Content-Typeがapplication/schema+jsonではない応答を受信した場合に類似しています。実装は確かにそれをスキーマとして解釈しようとすることができますが、元のサーバーはそれが実際にそのようなものであるという保証を提供しませんでした。したがって、それをそのように解釈することにはセキュリティ上の意味があり、予測できない結果を生み出す可能性があります。 ¶
"$defs"と同一の構文とセマンティクスを持つ単層のカスタムキーワードは、介在する"$id"キーワードを許可しないため、参照ターゲットをスキーマとして使用しようとする実装の下では正しく動作します。ただし、この動作は実装固有のものであり、相互運用性のために依存してはなりません。¶
JSONは、自動化されたAPIやロボット向けにHTTPサーバーで広く採用されています。このセクションでは、メディアタイプとWebリンキング [RFC8288]をサポートするプロトコルで使用した場合に、よりRESTfulな方法でJSONドキュメントの処理を強化する方法について説明します。¶
スキーマによって記述されたインスタンスは、Linked Data Protocol 1.0, 8.1節 [W3C.REC-ldp-20150226]で定義されているように、リンク関係 "describedby" を使用してダウンロード可能なJSONスキーマへのリンクを提供することが推奨されます。¶
HTTPでは、このようなリンクはLinkヘッダー [RFC8288]を使用して任意の応答に添付できます。このようなヘッダーの例は次のようになります。¶
Link: <https://example.com/my-hyper-schema>; rel="describedby"¶
ネットワークを介したハイパーメディアシステムに使用する場合、HTTP [RFC7231]は、スキーマを配布するためのプロトコルとしてよく使用されます。クライアントがスキーマを必要な頻度よりも多くネットワーク経由でプルする場合、サーバーのメンテナーに問題を引き起こす可能性があります。代わりに、スキーマを長期間キャッシュすることが可能です。¶
HTTPサーバーは、JSONスキーマに長期間のキャッシュヘッダーを設定する必要があります。HTTPクライアントは、キャッシュヘッダーを監視し、その鮮度期間内にドキュメントを再要求しないようにする必要があります。分散システムは、共有キャッシュやキャッシュプロキシを利用する必要があります。¶
クライアントは、JSONスキーマの実装またはソフトウェア製品に固有のUser-Agentヘッダーを設定または先頭に追加する必要があります。シンボルは重要度の高い順にリストされるため、JSONスキーマライブラリの名前/バージョンは、より一般的なHTTPライブラリの名前(存在する場合)よりも前に記述する必要があります。例:¶
User-Agent: product-name/5.4.1 so-cool-json-schema/1.0.2 curl/7.43.0¶
クライアントは、サーバーオペレーターが潜在的に不正な動作をするスクリプトの所有者に連絡できるように、"From"ヘッダーを使用してリクエストを行うことができるようにする必要があります。¶
このセクションでは、他の語彙の基礎として使用することが推奨されるアプリケーターキーワードの語彙を定義します。¶
"$vocabulary"を使用しないメタスキーマは、そのURIがtrueの値で存在する場合と同様に、この語彙を必要とすると見なされるべきです。¶
アプリケーター語彙として知られる、この語彙の現在のURIは次のとおりです。<https://json-schema.dokyumento.jp/draft/2020-12/vocab/applicator>。¶
対応するメタスキーマの現在のURIは、https://json-schema.dokyumento.jp/draft/2020-12/meta/applicatorです。¶
スキーマキーワードは通常、互いの結果に影響を与えることなく、独立して動作します。¶
スキーマ作成者の便宜のため、この語彙のキーワードにはいくつかの例外があります。¶
これらのキーワードは、親スキーマが適用されているインスタンスと同じ場所でサブスキーマを適用します。これにより、サブスキーマの結果をさまざまな方法で結合または変更できます。¶
これらのキーワードのサブスキーマは、インスタンスを完全に独立して評価するため、そのようなサブスキーマの1つの結果が兄弟サブスキーマの結果に影響を与えてはなりません。したがって、サブスキーマは任意の順序で適用できます。¶
これらのキーワードは、サブスキーマのブール値アサーションの結果を結合または変更するための論理演算子に対応します。それらはアノテーション収集に直接的な影響はありませんが、同じアノテーションキーワードを異なる値でインスタンスの場所に適用できるようにします。アノテーションキーワードは、このような値を結合するための独自ルールを定義します。¶
このキーワードの値は、空ではない配列でなければなりません。配列の各項目は、有効なJSONスキーマでなければなりません。¶
インスタンスは、このキーワードの値によって定義されたすべてのスキーマに対して正常に検証される場合、このキーワードに対して正常に検証されます。¶
このキーワードの値は、空ではない配列でなければなりません。配列の各項目は、有効なJSONスキーマでなければなりません。¶
インスタンスは、このキーワードの値によって定義された少なくとも1つのスキーマに対して正常に検証される場合、このキーワードに対して正常に検証されます。アノテーションが収集されている場合、アノテーションが正常に検証された各サブスキーマから収集されるように、すべてのサブスキーマを調べる必要があることに注意してください。¶
このキーワードの値は、空ではない配列でなければなりません。配列の各項目は、有効なJSONスキーマでなければなりません。¶
インスタンスは、このキーワードの値によって定義された正確に1つのスキーマに対して正常に検証される場合、このキーワードに対して正常に検証されます。¶
これらのキーワードのうち3つは、別のサブスキーマの結果に基づいてサブスキーマの条件付き適用を実装するために連携します。4番目は、特定の条件付きケースのショートカットです。¶
"if"、"then"、および "else" は、サブスキーマの境界を越えて相互に作用してはなりません。言い換えれば、"allOf" の1つのブランチ内の "if" は、別のブランチ内の "then" または "else" に影響を与えてはなりません。¶
"if"、"then"、または "else" が存在しない場合のデフォルトの動作はありません。特に、空のスキーマが存在する場合として扱ってはならず、"if" が存在しない場合は、"then" と "else" の両方を完全に無視する必要があります。¶
このキーワードの値は、有効なJSONスキーマでなければなりません。¶
このキーワードのサブスキーマの検証結果は、全体的な検証結果に直接的な影響を与えません。むしろ、どの "then" または "else" キーワードが評価されるかを制御します。¶
このキーワードのサブスキーマに対して正常に検証されるインスタンスは、存在する場合は、"then" キーワードのサブスキーマ値に対しても有効である必要があります。¶
このキーワードのサブスキーマに対して検証に失敗したインスタンスは、存在する場合は、"else" キーワードのサブスキーマ値に対しても有効である必要があります。¶
アノテーション (7.7節)が収集されている場合は、キーワードが "then" または "else" のいずれもなしで存在する場合を含め、通常の方法でこのキーワードのサブスキーマから収集されます。¶
このキーワードの値は、有効なJSONスキーマでなければなりません。¶
「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 の注釈結果が生成され、残りのすべての配列要素がこのキーワードのサブスキーマに対して評価されたことを示します。この注釈は、未評価語彙の「unevaluatedItems」の動作に影響を与えます。¶
このキーワードを省略することは、空のスキーマと同じアサーション動作になります。¶
実装は、「prefixItems」配列の存在とサイズを直接確認するなど、同じ効果を生み出す別の方法でこのキーワードを実装または最適化することを選択できます。注釈収集をサポートしない実装は、そうする必要があります。¶
このキーワードの値は、有効な JSON Schema でなければなりません。¶
配列インスタンスは、少なくとも1つの要素が指定されたスキーマに対して有効である場合、「contains」に対して有効です。ただし、「minContains」が存在し、値が0である場合は、配列インスタンスは、その要素のいずれも指定されたスキーマに対して有効でない場合でも、「contains」キーワードに対して有効と見なされる必要があります。¶
このキーワードは、このキーワードがサブスキーマを適用するときに正常に検証されたインデックスの配列(昇順)である注釈値を生成します。サブスキーマがインスタンスのすべてのインデックスに適用された場合に正常に検証された場合、値はブール値 "true"になることがあります。このキーワードのスキーマが適用されるインスタンス配列が空の場合は、注釈が存在する必要があります。¶
この注釈は、未評価語彙の「unevaluatedItems」の動作に影響を与え、また、検証語彙の「minContains」および「maxContains」キーワードを実装するためにも使用される場合があります。¶
他のキーワードで使用するための注釈を収集するために、最初のマッチが見つかった後でも、すべての配列要素にサブスキーマを適用する必要があります。これは、すべての可能な注釈が収集されることを保証するためです。¶
「properties」の値はオブジェクトでなければなりません。このオブジェクトの各値は、有効な JSON Schema でなければなりません。¶
インスタンスとこのキーワードの値内の名前の両方に現れる各名前について、その名前の子インスタンスが対応するスキーマに対して正常に検証された場合、検証は成功します。¶
このキーワードの注釈結果は、このキーワードによって一致したインスタンスプロパティ名のセットです。この注釈は、「additionalProperties」(この語彙内)および未評価語彙の「unevaluatedProperties」の動作に影響を与えます。¶
このキーワードを省略することは、空のオブジェクトと同じアサーション動作になります。¶
「patternProperties」の値はオブジェクトでなければなりません。このオブジェクトの各プロパティ名は、ECMA-262 正則表現方言に従って、有効な正規表現である必要があります。このオブジェクトの各プロパティ値は、有効な JSON Schema でなければなりません。¶
このキーワードの値のプロパティ名として現れる任意の正規表現に一致する各インスタンス名について、その名前の子インスタンスが一致する正規表現に対応する各スキーマに対して正常に検証された場合、検証は成功します。¶
このキーワードの注釈結果は、このキーワードによって一致したインスタンスプロパティ名のセットです。この注釈は、「additionalProperties」(この語彙内)および「unevaluatedProperties」(未評価語彙内)の動作に影響を与えます。¶
このキーワードを省略することは、空のオブジェクトと同じアサーション動作になります。¶
「additionalProperties」の値は、有効な JSON Schema でなければなりません。¶
このキーワードの動作は、同じスキーマオブジェクト内の「properties」および「patternProperties」の存在と注釈結果によって異なります。「additionalProperties」による検証は、「properties」または「patternProperties」のいずれかの注釈結果に現れないインスタンス名の子値にのみ適用されます。¶
そのようなすべてのプロパティについて、子インスタンスが「additionalProperties」スキーマに対して検証された場合、検証は成功します。¶
このキーワードの注釈結果は、このキーワードのサブスキーマによって検証されたインスタンスプロパティ名のセットです。この注釈は、未評価語彙の「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)を参照してください。¶
「propertyNames」の値は、有効な JSON Schema でなければなりません。¶
インスタンスがオブジェクトの場合、このキーワードは、インスタンス内のすべてのプロパティ名が提供されたスキーマに対して検証された場合に有効です。スキーマがテストしているプロパティ名は常に文字列であることに注意してください。¶
このキーワードを省略することは、空のスキーマと同じ動作になります。¶
これらのキーワードの目的は、スキーマ作成者が、隣接するキーワードの動的スコープのサブスキーマによって正常に評価されなかった配列項目またはオブジェクトプロパティにサブスキーマを適用できるようにすることです。¶
これらのインスタンス項目またはプロパティは、「anyOf」のブランチ内のアサーションが失敗した場合など、1つ以上の隣接するキーワードサブスキーマに対して評価が失敗している可能性があります。このような失敗した評価は、項目またはプロパティが評価されたかどうかの判断には考慮されません。成功した評価のみが考慮されます。¶
配列内の項目またはオブジェクトプロパティが「正常に評価」された場合、それは論理的に、期待されるオブジェクトまたは配列の表現に関して有効であると見なされます。たとえば、サブスキーマが2〜4個の車輪を必要とする車を表しており、「wheels」の値が6の場合、インスタンスオブジェクトは車であると「評価」されず、「wheels」プロパティは「評価されていない(既知のものとして成功)」と見なされ、注釈を保持しません。¶
隣接するキーワードは同じスキーマオブジェクト内のキーワードであり、動的スコープのサブスキーマには、字句サブスキーマだけでなく参照ターゲットも含まれることを思い出してください。¶
これらのキーワードの動作は、検証されるインスタンスの場所に適用される隣接するキーワードの注釈結果に依存します。¶
「$vocabulary」を使用しないメタスキーマは、そのURIがtrueの値で存在するかのように、この語彙を必要とすると見なす必要があります。¶
Unevaluated Applicator語彙として知られる、この語彙の現在のURIは次のとおりです: <https://json-schema.dokyumento.jp/draft/2020-12/vocab/unevaluated>。¶
対応するメタスキーマの現在のURIは次のとおりです: https://json-schema.dokyumento.jp/draft/2020-12/meta/unevaluated。¶
スキーマキーワードは通常、互いの結果に影響を与えることなく、独立して動作します。ただし、この語彙のキーワードは注目すべき例外です。¶
「unevaluatedItems」の値は、有効なJSONスキーマである必要があります。¶
このキーワードの動作は、検証されるインスタンスの場所に適用される隣接するキーワードの注釈結果に依存します。具体的には、「unevaluatedItems」キーワードに隣接する場合に、それらのキーワードから得られる「prefixItems」、「items」、および「contains」からの注釈です。これらの3つの注釈に加えて、「unevaluatedItems」は、隣接するすべてのインプレースアプリケータ(セクション10.2)キーワードからも得られます。これには、このドキュメントで定義されているインプレースアプリケータが含まれますが、これに限定されません。¶
関連する注釈が存在しない場合、「unevaluatedItems」サブスキーマは、配列内のすべての場所に適用する必要があります。関連する注釈のいずれかからブール値のtrueが存在する場合、「unevaluatedItems」は無視する必要があります。それ以外の場合、サブスキーマは、「contains」の注釈値に含まれていない「prefixItems」の最大注釈値よりも大きいインデックスに適用する必要があります。¶
これは、「prefixItems」、「items」、「contains」、およびすべてのインプレースアプリケータを、このキーワードを評価する前に評価する必要があることを意味します。拡張キーワードの作成者は、このキーワードの後に評価する必要があるインプレースアプリケータを定義してはなりません。¶
「unevaluatedItems」サブスキーマがインスタンス配列内の任意の位置に適用された場合、「items」の動作と同様に、ブール値のtrueの注釈結果を生成します。この注釈は、親スキーマの「unevaluatedItems」の動作に影響を与えます。¶
このキーワードを省略すると、空のスキーマと同じアサーション動作になります。¶
「unevaluatedProperties」の値は、有効なJSONスキーマである必要があります。¶
このキーワードの動作は、検証されるインスタンスの場所に適用される隣接するキーワードの注釈結果に依存します。具体的には、「unevaluatedProperties」キーワードに隣接する場合に、それらのキーワードから得られる「properties」、「patternProperties」、および「additionalProperties」からの注釈です。これらの3つの注釈に加えて、「unevaluatedProperties」は、隣接するすべてのインプレースアプリケータ(セクション10.2)キーワードからも得られます。これには、このドキュメントで定義されているインプレースアプリケータが含まれますが、これに限定されません。¶
「unevaluatedProperties」を使用した検証は、検証されるインスタンスの場所に適用される「properties」、「patternProperties」、「additionalProperties」、または「unevaluatedProperties」の注釈結果に含まれていないインスタンス名の子供の値にのみ適用されます。¶
このようなすべてのプロパティについて、子インスタンスが「unevaluatedProperties」スキーマに対して検証に成功した場合、検証は成功します。¶
これは、「properties」、「patternProperties」、「additionalProperties」、およびすべてのインプレースアプリケータを、このキーワードを評価する前に評価する必要があることを意味します。拡張キーワードの作成者は、このキーワードの後に評価する必要があるインプレースアプリケータを定義してはなりません。¶
このキーワードの注釈結果は、このキーワードのサブスキーマによって検証されたインスタンスプロパティ名のセットです。この注釈は、親スキーマの「unevaluatedProperties」の動作に影響を与えます。¶
このキーワードを省略すると、空のスキーマと同じアサーション動作になります。¶
JSONスキーマは、プラットフォームに依存しないように定義されています。そのため、プラットフォーム間の互換性を高めるために、実装は標準の検証出力形式に準拠する必要があります。このセクションでは、コンシューマーが検証結果を適切に解釈するために必要な最小要件について説明します。¶
JSONスキーマの出力は、セクション4.2.1で説明されているJSONスキーマデータインスタンスモデルを使用して定義されます。実装は、特定の言語およびプラットフォームでサポートされている範囲で、これから逸脱する可能性がありますが、シリアル化またはその他の手段によって、ここで定義されているJSON形式に変換可能であることが推奨されます。¶
この仕様では、4つの出力形式を定義しています。各形式の要件については、「出力構造」のセクションを参照してください。¶
実装は、「フラグ」、「基本」、または「詳細」形式のうち少なくとも1つを提供する必要があり、「詳細」形式を提供してもよい。 「詳細」または「詳細」形式の1つ以上を提供する場合は、「フラグ」形式も提供する必要があります。実装は、サポートする形式をドキュメントで指定する必要があります。¶
単純な「フラグ」出力に加えて、スキーマまたはインスタンスのデバッグに役立つ追加情報が有用です。各サブ結果には、少なくともこのセクションに含まれる情報が含まれている必要があります。¶
これらのコンポーネントすべてを含む単一のオブジェクトが出力ユニットと見なされます。¶
実装は追加情報を提供することを選択してもよい。¶
検証パスに従う検証キーワードの相対位置。値はJSONポインタとして表現する必要があり、「$ref」や「$dynamicRef」などの参照によるアプリケータを含める必要があります。¶
/properties/width/$ref/minimum¶
このポインタには、これらの参照によるアプリケータキーワードが含まれているため、通常のJSONポインタプロセスでは解決できない可能性があることに注意してください。¶
この情報のJSONキーは「keywordLocation」です。¶
検証キーワードの絶対参照解除された場所。値は、JSONポインタフラグメントを使用した関連スキーマリソースの正規URIを使用する完全URIとして表現する必要があり、非終端パスコンポーネントとして「$ref」や「$dynamicRef」などの参照によるアプリケータを含めないでください。エラーまたは注釈が、解決できない参照などのそのキーワードに対するものである場合、そのようなキーワードで終わる可能性があります。ここで「絶対」とは、「絶対ファイルシステムパス」の意味(完全な場所を意味する)であり、RFC 3986の「絶対-URI」の用語(スキーム付きだがフラグメントなしを意味する)ではないことに注意してください。キーワードの絶対位置には、キーワードを識別するためのフラグメントが含まれます。¶
https://example.com/schemas/common#/$defs/count/minimum¶
この情報は、動的スコープが参照を通過しなかった場合、またはスキーマがその「$id」として絶対URIを宣言しない場合にのみ省略できます。¶
この情報のJSONキーは「absoluteKeywordLocation」です。¶
検証中のインスタンス内のJSON値の位置。値はJSONポインタとして表現する必要があります。¶
この情報のJSONキーは「instanceLocation」です。¶
検証によって生成されるエラーまたは注釈。¶
エラーの場合、メッセージの具体的な表現は、この仕様では定義されていません。実装はこれを提供する必要があります。¶
注釈の場合、注釈を生成する各キーワードは、その形式を指定します。デフォルトでは、キーワードの値です。¶
検証に失敗した場合のJSONキーは「error」です。検証に成功した場合は「annotation」です。¶
この2つの階層構造において、このプロパティはネストされたエラーとアノテーションを保持します。¶
検証に失敗した場合のネストされた結果のJSONキーは "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 } ]¶
このインスタンスは検証に失敗し、エラーを生成しますが、アノテーションを生成するスキーマを渡す例を推測するのは簡単です。¶
具体的には、生成されるエラーは次のとおりです。¶
これらの例で示されているエラーメッセージの文言は、この仕様の要件ではないことに注意してください。実装は、対象者向けに調整されたエラーメッセージを作成するか、ユーザーが独自にメッセージを作成できるテンプレートメカニズムを提供する必要があります。¶
最も単純なケースでは、"valid" プロパティのブール値の結果のみを満たす必要があります。¶
{ "valid": false }¶
この形式ではエラーやアノテーションが返されないため、結果が判断できたらすぐに失敗または成功を返すために、実装でショートサーキットロジックを使用することをお勧めします。たとえば、"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` プロパティを含めることも推奨されます。¶
この出力構造は非常に大きくなる可能性があるため、簡潔にするために小さな例をここで示します。上記の例の完全な出力構造の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." } ] } ] }¶
便宜上、実装によって生成された出力を検証するためにJSONスキーマが提供されています。そのURIは次のとおりです: https://json-schema.dokyumento.jp/draft/2020-12/output/schema。¶
スキーマとインスタンスはどちらもJSON値です。そのため、RFC 8259 [RFC8259] で定義されているすべてのセキュリティに関する考慮事項が適用されます。¶
インスタンスとスキーマはどちらも、公開インターネットサーバーに展開するために信頼できないサードパーティによって頻繁に記述されます。バリデーターは、スキーマに対する解析と検証が過度のシステムリソースを消費しないように注意する必要があります。バリデーターは、無限ループに陥ってはなりません。¶
悪意のある第三者が、非常に大きな値のコピーをアノテーションとして繰り返し収集させる可能性があります。実装は、このようなシナリオでのシステムリソースの過剰な消費を防ぐ必要があります。¶
サーバーは、悪意のある第三者が、既存または非常に類似した "$id" を持つスキーマをアップロードすることによって既存のスキーマの機能を変更できないようにする必要があります。¶
個々のJSONスキーマ語彙にも、独自のセキュリティに関する考慮事項がある可能性があります。詳細については、それぞれの仕様を参照してください。¶
スキーマの作成者は、悪意のある実装が仕様に違反してエンドユーザーに "$comment" の内容を表示したり、そのような動作が予想される場合にそれらを削除できなかったりする可能性があるため、"$comment" の内容に注意する必要があります。¶
悪意のあるスキーマの作成者は、"$comment" 内に実行可能コードやその他の危険なマテリアルを配置する可能性があります。実装は、"$comment" の内容に基づいて解析したり、その他のアクションを実行したりしてはなりません。¶
JSONスキーマの提案されたMIMEメディアタイプは、次のように定義されています。¶
JSONスキーマ固有のメディアタイプを必要とするJSONスキーマインスタンスの提案された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 ポインタ [RFC6901] (ルートスキーマに対する相対) にあるスキーマは、以下のベース URI を持ち、上記の5項および9.2.1項に従って、リストされた任意の URI で識別可能です。¶
注: URI のフラグメント部分は、URI を正規にするか非正規にするかではなく、(フラグメントを含む完全な URI の一部としての) 使用されるベース URI が、結果の完全な URI の正規性を決定します。 複数の「正規」URI? これは潜在的に混乱を招く可能性があることを認識しており、詳細なコメントについては、JSON ポインタフラグメントと埋め込みスキーマ リソース (9.2.1 項) セクションにある CREF を参照してください。¶
参照 ("$ref") がどのように、どこに現れるかに基づいて、スキーマ ドキュメントを再配置するためにさまざまなツールが作成されてきました。この付録では、この仕様に準拠しているユースケースとアクションについて説明します。¶
一緒に使用することを意図した一連のスキーマ リソースは、それぞれ独自のスキーマ ドキュメント、すべて同じスキーマ ドキュメント、またはその間の任意の粒度のドキュメント グループで編成できます。¶
さまざまな種類の参照削除を実行するための多数のツールが存在します。これの一般的なケースは、そのファイル内で解決できるすべての参照を持つ単一のファイルを生成することです。これは通常、配布を簡素化するため、または JSON スキーマライブラリのさまざまな呼び出しが多数のリソースを追跡してロードする必要がないようにコーディングを簡素化するために行われます。¶
この変換は、すべての静的参照 (例えば "$ref") が、ベースとして正規リソース URI を使用して URI に解決される URI 参照を使用し、すべてのスキーマ リソースがルート スキーマに絶対 URI として "$id" を持つ限り、安全かつ可逆的に実行できます。¶
これらの条件が満たされると、各外部リソースを "$defs" の下にコピーでき、リソースのスキーマオブジェクト間の参照を壊したり、検証またはアノテーションの結果のいずれかの側面を変更したりすることはありません。"$defs" の下のスキーマの名前は、埋め込みリソースの正規 URI に表示されないため、それぞれが一意であると仮定して、動作に影響を与えません。¶
すべての参照を削除して単一のスキーマ ドキュメントを生成しようとすると、すべての場合に、元の形式と同一の動作を持つスキーマが生成されるわけではありません。¶
"$ref" は他のキーワードと同様に扱われ、同じスキーマ オブジェクトで他のキーワードを使用できるようになり、すべての場合に非再帰的な "$ref" の削除を完全にサポートするには、比較的複雑なスキーマ操作が必要になる可能性があります。この仕様の範囲外であり、スキーマ構造だけでなく、意図された使用法にも依存するため、安全な "$ref" 削除変換のセットを決定または提供することはできません。¶
以下に示すのは、ツリー内の各ノードが任意の型の「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つのスキーマをロードすると、それぞれに「node」という名前の "$dynamicAnchor" が存在することに気づきます (これは名前のみであるため、「#」がないことに注意してください)。結果として、次の完全なスキーマ URI が生成されます。¶
さらに、JSON スキーマの実装では、これらのフラグメントが "$dynamicAnchor" で作成されたという事実を追跡します。¶
インスタンスに「strict-tree」スキーマを適用すると、「tree」スキーマへの「$ref」をたどり、その「children」サブスキーマを調べると、その「items」サブスキーマに「$dynamicRef:」から「#node」への参照 (URI フラグメント構文の場合は「#」に注意) が見つかります。その参照は "https://example.com/tree#node" に解決されます。これは "$dynamicAnchor" で作成されたフラグメントを持つ URI です。したがって、参照をたどる前に動的なスコープを調べる必要があります。¶
この時点で、動的パスは "#/$ref/properties/children/items/$dynamicRef" であり、動的スコープには (最も外側のスコープから最も内側のスコープまで) 以下が含まれます。¶
プレーンな名前のフラグメントを探しているため、スキーマ リソース内の任意の場所で定義できるため、JSON ポインタ フラグメントはこのチェックには関係ありません。つまり、それらのフラグメントを削除し、連続する重複を削除して、次のものを生成できます。¶
この場合、最も外側のリソースには "$dynamicAnchor" で定義された "node" フラグメントもあります。したがって、"$dynamicRef" を "https://example.com/tree#node" に解決する代わりに、"https://example.com/strict-tree#node" に解決します。¶
このようにして、「tree」スキーマの再帰は、「strict-tree」をインスタンスルートに適用するだけでなく、「tree」をインスタンスの子に適用するのではなく、「strict-tree」のルートに再帰します。¶
この例は、各スキーマの同じ場所、特にリソースルートスキーマの両方の "$dynamicAnchor" を示しています。プレーンな名前のフラグメントは JSON 構造とは独立しているため、ノードスキーマオブジェクトの1つまたは両方が "$defs" の下に移動された場合でも、これは同様に機能します。動的参照を解決する方法を教えているのは、JSON構造の相関関係ではなく、一致する "$dynamicAnchor" 値です。¶
ボキャブラリーの作成者は、ボキャブラリーが広く使用され、他のボキャブラリーと組み合わされる可能性がある場合、キーワード名の衝突を避けるように注意する必要があります。JSON Schema は、公式な名前空間システムを提供していませんが、キーワード名を制約しないため、任意の数の名前空間アプローチが可能です。¶
ボキャブラリーは、別のボキャブラリーのキーワードの動作に関して、キーワードの動作を定義したり、別のボキャブラリーのキーワードを、制限されたり拡張されたりした許容値のセットで使用するなどして、相互に構築できます。このようなボキャブラリーの再利用がすべて、構築元のボキャブラリーと互換性のある新しいボキャブラリーになるわけではありません。ボキャブラリーの作成者は、期待される互換性のレベル(存在する場合)を明確に文書化する必要があります。¶
メタスキーマの作成者は、同じキーワードに対して構文またはセマンティクスが競合する複数のボキャブラリーを組み合わせるために "$vocabulary" を使用しないでください。セマンティックの競合は、通常、スキーマ検証では検出できないため、実装はこのような競合を検出することは期待されていません。競合するボキャブラリーが宣言された場合、結果として生じる動作は未定義です。¶
ボキャブラリーの作成者は、ボキャブラリーのキーワードの予期される使用法を独自に検証するメタスキーマを提供する必要があります(SHOULD)。このようなメタスキーマは、追加のキーワードを禁止すべきではなく(SHOULD NOT)、コアボキャブラリーのキーワードを禁止してはなりません(MUST NOT)。¶
メタスキーマの作成者は、"allOf" (セクション 10.2.1.1)キーワードを使用して、各ボキャブラリーのメタスキーマを参照することをお勧めしますが、特定のユースケースにはメタスキーマを構築するための他のメカニズムが適切な場合があります。¶
メタスキーマの再帰的な性質により、既存のメタスキーマを拡張するために "$dynamicAnchor" および "$dynamicRef" キーワードが特に役立ちます。これは、検証メタスキーマを拡張する JSON ハイパースキーマメタスキーマで確認できます。¶
メタスキーマは、宣言されたボキャブラリーに関連付けられたメタスキーマが記述するものを超えて、どのボキャブラリーにも存在しないキーワードを記述するなど、追加の制約を課す場合があります。これにより、使用法をボキャブラリーのサブセットに制限したり、再利用を意図していないローカルで定義されたキーワードを検証したりできます。¶
ただし、メタスキーマは、ボキャブラリーが予期するのとは異なるJSON型を要求するなど、宣言するボキャブラリーと矛盾してはなりません。結果として生じる動作は未定義です。¶
任意の環境でのボキャブラリーのサポートをテストする必要がなく、ローカルで使用することを目的としたメタスキーマは、"$vocabulary" を完全に省略しても安全です。¶
このメタスキーマは、コアボキャブラリーとアプリケーターボキャブラリーの両方を、拡張ボキャブラリーとともに明示的に宣言し、それらのメタスキーマを "allOf" で結合します。拡張ボキャブラリーのメタスキーマ(そのボキャブラリーのキーワードのみを記述)は、メインのメタスキーマの例の後に示されています。¶
メインのメタスキーマの例は、特に実装が複雑な "unevaluated" で始まるキーワードを禁止することにより、未評価ボキャブラリーの使用法も制限します。これにより、他のボキャブラリーによって定義されたセマンティクスまたはキーワードのセットは変更されません。これにより、このメタスキーマを使用するスキーマが "unevaluated" で始まるキーワードを使用しようとすると、このメタスキーマに対する検証が失敗することが保証されるだけです。¶
最後に、このメタスキーマは、どのボキャブラリーにも含まれていないキーワード "localKeyword" の構文を記述します。おそらく、このメタスキーマの実装者とユーザーは、"localKeyword" のセマンティクスを理解するでしょう。JSON Schema は、ボキャブラリー以外でキーワードのセマンティクスを表現するメカニズムを定義していないため、それらが理解される特定の環境以外での使用には適していません。¶
このメタスキーマは、一般用途のためにいくつかのボキャブラリーを組み合わせています。¶
{ "$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" のセマンティックな意味の背後にあるロジックを定義するのはボキャブラリーです。セマンティクス(この例では、インスタンス値がスキーマ内のキーワードの値として提供される日付以降の日付である必要があること)を理解していない場合、実装は構文的な使用法のみを検証できます。この場合、これは、日付形式の文字列であることを検証することです("format" が純粋にアノテーションとして機能する場合でも検証されるように "pattern" を使用します。これは検証仕様 [json-schema-validation]で説明されています)。¶
参照の存在は検証結果に対して透過的であることが期待されますが、コードジェネレーターや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" プロパティはそうではありません。これは、別のクラスのインスタンスではなく、サブフィールドを持つ単なるフィールドです。¶
このスタイルの使用法では、アノテーションは参照と同じオブジェクト内にある必要があり、参照として認識可能である必要があります。¶
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 の各氏に感謝いたします。¶
このセクションは、インターネットドラフトステータスを離れる前に削除されます。¶