インターネット技術特別調査委員会 | A. ライト (編) |
インターネットドラフト | |
対象ステータス: 情報提供 | H. アンドリュース (編) |
有効期限: 2020年3月20日 | |
B. ハットン (編) | |
ウェルカムサンガー研究所 | |
G. デニス | |
2019年9月17日 |
JSONスキーマ: JSONドキュメントを記述するためのメディアタイプ
draft-handrews-json-schema-02
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か月間有効なドラフト文書であり、いつでも他の文書によって更新、置換、または廃止される可能性があります。インターネットドラフトを参考資料として使用したり、「作業中」以外のものとして引用したりすることは不適切です。
このインターネットドラフトは、2020年3月20日に失効します。
Copyright (c) 2019 IETF Trust およびドキュメントの作成者として特定された人物。無断複写・転載を禁じます。
このドキュメントは、BCP 78 およびこのドキュメントの発行日に有効な IETF Trust の IETF ドキュメントに関する法的規定 (https://trustee.ietf.org/license-info) に準拠しています。このドキュメントに関するお客様の権利と制限を説明しているため、これらのドキュメントを注意深く確認してください。このドキュメントから抽出されたコードコンポーネントには、Trust Legal Provisions のセクション 4.e で説明されている Simplified BSD License のテキストを含める必要があり、Simplified BSD License で説明されているように、保証なしで提供されます。
JSONスキーマは、JSONデータの構造を定義するためのJSONメディアタイプです。JSONスキーマは、JSONデータの検証、ドキュメント化、ハイパーリンクナビゲーション、および対話制御を定義することを目的としています。
この仕様は、参照による別のJSONスキーマへのポインタ、JSONスキーマ参照の逆参照、使用されている語彙の指定、および期待される出力の定義など、JSONスキーマのコア用語とメカニズムを定義します。
他の仕様では、検証、リンク、アノテーション、ナビゲーション、および対話に関するアサーションを実行する語彙を定義します。
このドキュメントのキーワード「MUST」、「MUST NOT」、「REQUIRED」、「SHALL」、「SHALL NOT」、「SHOULD」、「SHOULD NOT」、「RECOMMENDED」、「MAY」、および「OPTIONAL」は、RFC 2119 で説明されているように解釈されるものとします。
このドキュメントの用語「JSON」、「JSONテキスト」、「JSON値」、「メンバー」、「要素」、「オブジェクト」、「配列」、「数値」、「文字列」、「ブール値」、「true」、「false」、および「null」は、RFC 8259 で定義されているように解釈されるものとします。
このドキュメントでは、JSONデータを記述するためのJSONスキーマを識別するために、新しいメディアタイプ "application/schema+json" を提案します。また、追加の統合機能を提供するために、さらにオプションのメディアタイプ "application/schema-instance+json" を提案します。JSONスキーマ自体はJSONドキュメントです。この仕様および関連する仕様では、作成者がJSONデータをいくつかの方法で記述できるようにするキーワードを定義します。
JSONスキーマは、キーワードを使用して、JSONインスタンスの制約をアサートするか、追加情報でそれらのインスタンスにアノテーションを付けます。追加のキーワードは、より複雑なJSONデータ構造に対して、または何らかの条件に基づいてアサーションとアノテーションを適用するために使用されます。
再利用を容易にするために、キーワードは語彙に編成できます。語彙は、構文とセマンティクスを備えたキーワードのリストで構成されています。
JSONスキーマは、追加の語彙を定義するか、それほど形式的ではない方法で、語彙の外に追加のキーワードを定義することによって拡張できます。認識されない個々のキーワードは無視されますが、どの語彙が使用中であるかを宣言するときに、認識されない語彙に関する動作を制御できます。
このドキュメントでは、すべての実装でサポートする必要があり、無効にできないコア語彙を定義します。そのキーワードには、必要な性質を強調するために「$」文字が前に付いています。この語彙は、"application/schema+json" メディアタイプの機能に不可欠であり、他の語彙のロードをブートストラップするために使用されます。
さらに、このドキュメントでは、サブスキーマを条件付きで適用するため、およびオブジェクトと配列の内容にサブスキーマを適用するためのキーワードの推奨される語彙を定義します。この語彙またはそれに非常によく似た語彙は、それらのスキーマがアサーション検証、アノテーション、またはその両方を目的としているかどうかにかかわらず、自明ではないJSONインスタンスのスキーマを作成するために必要です。必須のコア語彙の一部ではありませんが、最大限の相互運用性のために、この追加の語彙はこのドキュメントに含まれており、その使用が強く推奨されます。
構造検証やハイパーメディアアノテーションなどの目的のための追加の語彙は、他のドキュメントで定義されています。
JSONドキュメントは、application/jsonメディアタイプで記述された情報リソース (オクテットのシリーズ) です。
JSONスキーマでは、定義するデータモデルのため、「JSONドキュメント」、「JSONテキスト」、および「JSON値」という用語は交換可能です。
JSONスキーマは、JSONドキュメントに対してのみ定義されています。ただし、JSONスキーマデータモデルに従って解析または処理できるドキュメントまたはメモリ構造は、CBOR などのメディアタイプを含め、JSONスキーマに対して解釈できます。
スキーマが適用されるJSONドキュメントは「インスタンス」と呼ばれます。
JSONスキーマは、データモデルに従ってドキュメントを解釈します。このデータモデルに従って解釈されるJSON値は、「インスタンス」と呼ばれます。
インスタンスには、6つのプリミティブ型のうちの1つと、型に応じて可能な値の範囲があります。
データモデル内で等しい数値の異なる字句表現を含む、空白と書式に関する懸念は、JSON Schema の範囲外です。JSON Schema の語彙で、字句表現の違いを扱う必要がある場合は、元の JSON 表現の Unicode 文字に依存するのではなく、データモデル内でフォーマットされた文字列を正確に解釈するためのキーワードを定義すべきです。
オブジェクトは同じキーを持つプロパティを 2 つ持つことができないため、単一のオブジェクト内で同じキー("string" 生成規則)を持つ 2 つのプロパティ("member" 生成規則)を定義しようとする JSON ドキュメントの動作は未定義です。
JSON Schema の語彙は、独自の拡張型システムを自由に定義できることに注意してください。これは、ここで定義されているコアデータモデルの型と混同しないでください。例として、「integer」は語彙がキーワードの値として定義するのに妥当な型ですが、データモデルでは整数と他の数値を区別しません。
JSON Schema は、"+json" 構造化構文サフィックスを使用するメディアタイプだけでなく、"application/json" ドキュメントでも完全に機能するように設計されています。
スキーマを操作するのに役立つ一部の機能は、各メディアタイプによって定義されます。具体的には、メディアタイプパラメーターと URI フラグメント識別子の構文とセマンティクスです。これらの機能は、それぞれコンテンツネゴシエーションとインスタンス内の特定の場所の URI を計算するのに役立ちます。
この仕様では、インスタンスの作成者がこれらの目的でパラメーターとフラグメント識別子を最大限に活用できるようにするために、"application/schema-instance+json" メディアタイプを定義します。
2 つの JSON インスタンスは、同じ型を持ち、データモデルに従って同じ値を持つ場合にのみ等しいと言えます。具体的には、これは次のことを意味します。
この定義に含まれるのは、配列は同じ長さでなければならず、オブジェクトは同じ数のメンバーを持たなければならず、オブジェクトのプロパティは順序付けされておらず、同じキーを持つ複数のプロパティを定義する方法がなく、単なる書式の違い(インデント、コンマの位置、末尾のゼロ)は重要ではないということです。
JSON Schema ドキュメント、または単にスキーマとは、インスタンスを記述するために使用される JSON ドキュメントです。スキーマ自体はインスタンスとして解釈できますが、常に "application/schema-instance+json" ではなく "application/schema+json" メディアタイプを付与する必要があります。"application/schema+json" メディアタイプは、"application/schema-instance+json" によって提供されるメディアタイプパラメーターとフラグメント識別子の構文とセマンティクスのスーパーセットを提供するために定義されています。
JSON Schema は、オブジェクトまたはブール値である必要があります。
インスタンスに適用されるオブジェクトプロパティは、キーワード、またはスキーマキーワードと呼ばれます。大まかに言って、キーワードは次の 4 つのカテゴリのいずれかに分類されます。
キーワードは複数のカテゴリに分類される場合がありますが、アプリケーターはサブスキーマの結果に基づいてのみアサーション結果を生成する必要があります。サブスキーマとは独立した追加の制約を定義しないでください。
このドキュメントとそのコンパニオンの外部で定義された拡張キーワードも、他の動作を自由に定義できます。
JSON Schema には、スキーマキーワードではないプロパティを含めることができます。不明なキーワードは無視する必要があります。
空のスキーマは、プロパティがない、または不明なプロパティのみを持つ JSON Schema です。
ブール値のスキーマ値 "true" および "false" は、インスタンスの値に関係なく、常に自身をアサーション結果として生成する、自明なスキーマです。注釈の結果を生成することはありません。
これらのブール値スキーマは、スキーマ作成者の意図を明確にし、スキーマ処理の最適化を促進するために存在します。それらは、次のスキーマオブジェクト("not" は、このドキュメントで定義されているサブスキーマアプリケーション語彙の一部です)と同一に動作します。
空のスキーマオブジェクトは曖昧さがない一方で、"false" スキーマと同等のものがたくさんあります。ブール値を使用することで、意図が人間と実装の両方にとって明確になります。
スキーマ語彙、または単に語彙とは、キーワード、その構文、およびそのセマンティクスのセットです。語彙は、通常、特定の目的を中心に編成されています。検証、ハイパーメディア、ユーザーインターフェース生成など、JSON Schema のさまざまな使用法には、異なる語彙セットが含まれます。
語彙は、スキーマ作成者がスキーマを処理するために必要な語彙またはオプションの語彙を示すことができるため、JSON Schema の再利用の主要な単位です。語彙はメタスキーマの URI によって識別されるため、一般的な実装は、以前に不明な語彙をサポートするための拡張機能をロードできます。キーワードは語彙の外でサポートできますが、個々のキーワードの使用を示す同様のメカニズムはありません。
スキーマ自体を記述するスキーマは、メタスキーマと呼ばれます。メタスキーマは、JSON Schema を検証し、使用している語彙を指定するために使用されます。
通常、メタスキーマは語彙のセットを指定し、それらの語彙の構文に準拠するスキーマを検証します。ただし、メタスキーマと語彙は、メタスキーマが語彙の仕様で要求されるよりも厳密または緩やかにスキーマ適合を検証できるようにするために分離されています。メタスキーマは、正式な語彙の一部ではない追加のキーワードを記述および検証することもできます。
JSON Schema リソースは、正規に絶対 URIによって識別されるスキーマです。
ルートスキーマは、問題の JSON ドキュメント全体を構成するスキーマです。ルートスキーマは常にスキーマリソースであり、その URI は8.2.1項で説明されているように決定されます。
一部のキーワードはスキーマ自体を受け取り、JSON Schema をネストできるようにします。
{ "title": "root", "items": { "title": "array item" } }
このドキュメント例では、「array item」というタイトルのスキーマがサブスキーマであり、「root」というタイトルのスキーマがルートスキーマです。
ルートスキーマと同様に、サブスキーマはオブジェクトまたはブール値のいずれかです。
8.2.2項で説明したように、JSON Schema ドキュメントには複数の JSON Schema リソースを含めることができます。修飾なしで使用する場合、「ルートスキーマ」という用語は、ドキュメントのルートスキーマを指します。場合によっては、リソースルートスキーマについて説明します。リソースのルートスキーマは、最上位のスキーマオブジェクトであり、リソースがスタンドアロンの JSON Schema ドキュメントに抽出された場合にもドキュメントルートスキーマになります。
[RFC6839]の 3.1 項に従い、任意の +json メディアタイプに指定されたフラグメント識別子の構文とセマンティクスは、"application/json" に指定されたものと同じにする必要があります。(このドキュメントの発行時点では、"application/json" に定義されたフラグメント識別構文はありません。)
さらに、"application/schema+json" メディアタイプは、プレーン名と JSON ポインターの 2 つのフラグメント識別子構造をサポートしています。"application/schema-instance+json" メディアタイプは、JSON ポインターの 1 つのフラグメント識別子構造をサポートしています。
URI フラグメント識別子としての JSON ポインターの使用については、RFC 6901 で説明されています。2 つのフラグメント識別構文をサポートする "application/schema+json" の場合、空の文字列を含む JSON ポインター構文に一致するフラグメント識別子は、JSON ポインターフラグメント識別子として解釈する必要があります。
W3C のフラグメント識別子のベストプラクティスに従って、"application/schema+json" のプレーン名フラグメント識別子は、ローカルに名前付きのスキーマを参照するために予約されています。JSON ポインター構文に一致しないすべてのフラグメント識別子は、プレーン名フラグメント識別子として解釈する必要があります。
"application/schema+json" ドキュメント内でのプレーン名フラグメント識別子の定義と参照は、"$anchor" キーワードセクションで指定されています。
インスタンスは、JSONで定義されているように、任意の有効な JSON 値にすることができます。JSON Schema は型に制限を課していません。JSON Schema は、たとえば null を含む、任意の JSON 値を記述できます。
JSON Schema はプログラミング言語に依存せず、データモデルで記述されている値の全範囲をサポートします。ただし、一部の言語および JSON パーサーは、JSON で記述できる値の全範囲をメモリ内で表現できない場合があることに注意してください。
一部のプログラミング言語とパーサーは、浮動小数点数と整数で異なる内部表現を使用します。
一貫性のために、整数 JSON 数値は小数部でエンコードしないでください。
キーワードは、制約を表したり、インスタンス値を正規表現に制約したりするために、正規表現を使用する場合があります。これらの正規表現は、ECMA 262、セクション 15.10.1 で説明されている正規表現方言に従って有効である必要があります。
さらに、正規表現構成のサポートには大きなばらつきがあるため、スキーマ作成者は、次の正規表現トークンに限定する必要があります。
最後に、実装は、正規表現が先頭でも末尾でも固定されていると見なしてはなりません。つまり、たとえば、パターン "es" は "expression" に一致します。
追加のスキーマキーワードとスキーマ語彙は、任意のエンティティによって定義される場合があります。明示的な合意がない限り、スキーマ作成者は、そのようなサポートを明示的に文書化していない実装によって、これらの追加のキーワードと語彙がサポートされることを期待してはなりません。実装は、サポートしないキーワードを無視する必要があります。
実装は、直接サポートしていない語彙のハンドラーを登録またはロードする機能を提供する場合があります。そのようなハンドラーを登録および実装するための正確なメカニズムは、実装に依存します。
JSON Schemaキーワードは、いくつかの一般的な振る舞いカテゴリに分類されます。アサーションは、インスタンスが制約を満たしていることを検証し、ブール値の結果を生成します。アノテーションは、アプリケーションが自由に利用できる情報を提供します。アプリケーターは、サブスキーマをインスタンスの一部に適用し、それらの結果を組み合わせます。
拡張キーワードは、特にアノテーションが非常に柔軟であることを念頭に置きながら、これらのカテゴリ内に留まるべきです。複雑な振る舞いは、通常、スキーマキーワードとして直接実装するよりも、アノテーションデータに基づいてアプリケーションに委任する方が適切です。ただし、拡張キーワードは、特別な目的のために他の振る舞いを定義しても構いません。
スキーマに対するインスタンスの評価には、インスタンス内の適切な場所に対してスキーマ内のすべてのキーワードを処理することが含まれます。通常、アプリケーターキーワードは、アプリケーター(したがってサブスキーマも)を持たないスキーマオブジェクトに到達するまで処理されます。インスタンス内の適切な場所は、スキーマオブジェクトのアサーションおよびアノテーションキーワードに対して評価され、それらの結果は、アプリケーターのルールに従って親スキーマに収集されます。
親スキーマオブジェクトの評価は、すべてのサブスキーマが評価されると完了できます。ただし、状況によっては、アサーションの結果によって評価が途中で打ち切られる場合があります。アノテーションが収集されている場合、アサーション結果をさらに変更できないものも含め、すべてのアノテーション収集用のサブスキーマを調べる必要があるため、アサーション結果の一部を打ち切ることができません。
ほとんどのJSON Schemaキーワードは単独で評価できるか、またはせいぜい同じスキーマオブジェクト内の隣接するキーワードの値または結果を考慮に入れるだけで済みますが、いくつかのキーワードはより複雑な振る舞いをします。
キーワードの字句スコープは、オブジェクトと配列のネストされたJSONデータ構造によって決定されます。最大のスコープは、スキーマドキュメント全体です。最小のスコープは、サブスキーマを持たない単一のスキーマオブジェクトです。
キーワードは、URI参照などの部分的な値で定義でき、これは、JSONドキュメントの字句構造を通じて見つけられる別のURI参照または完全なURIなどの別の値に対して解決する必要があります。「$id」コアキーワードと「base」JSON Hyper-Schemaキーワードは、この種の振る舞いの例です。さらに、この仕様の「$ref」と「$recursiveRef」は、さらに値を解決する方法は変更しませんが、このように値を解決します。
「$schema」など一部のキーワードは、スキーマドキュメント全体の字句スコープに適用されるため、スキーマリソースのルートスキーマにのみ出現する必要があります。
他のキーワードは、スキーマの評価中に存在する動的スコープ(通常はインスタンスドキュメントと一緒)を考慮に入れる場合があります。最も外側の動的スコープは、処理が開始されるスキーマドキュメントのルートスキーマです。このルートスキーマから特定のキーワードまでのパス(解決された可能性のある「$ref」および「$recursiveRef」キーワードを含む)は、キーワードの「検証パス」と見なされます。[CREF1]または、これはルートではない場合でも、処理が開始されるスキーマオブジェクトである必要がありますか?これは、「$recursiveAnchor」がルートスキーマでのみ許可されているが、処理がサブスキーマで開始される場合にいくつかの影響があります。
字句スコープと動的スコープは、参照キーワードが検出されるまで整列します。参照キーワードに従うと、処理は1つの字句スコープから別の字句スコープに移動しますが、動的スコープの観点から見ると、参照に従うことは、値として存在するサブスキーマに降りていくのと違いはありません。動的スコープを通じて情報を解決するその参照の反対側のキーワードは、ローカルの字句的に囲む親を調べるのではなく、参照の元の側を動的な親と見なします。
動的スコープの概念は、主に「$recursiveRef」および「$recursiveAnchor」で使用され、高度な機能と見なされる必要があり、追加のキーワードを定義する場合は注意して使用する必要があります。エラーと収集されたアノテーションを報告するときにも表示されます。同じ字句スコープを異なる動的スコープで繰り返し再訪できる場合があるためです。このような場合は、エラーまたはアノテーションを生成した動的パスをユーザーに通知することが重要です。
キーワードの振る舞いは、サブスキーマおよび/または隣接するキーワードのアノテーション結果に関して定義される場合があります。このようなキーワードは、循環依存を引き起こしてはなりません。キーワードは、同じスキーマオブジェクト内の別のキーワードの有無に基づいて、その動作を変更する場合があります。
欠落しているキーワードは、falseのアサーション結果を生成してはならず、アノテーション結果を生成してはならず、独自の動作定義の一部として他のスキーマを評価させてはなりません。ただし、欠落しているキーワードがアノテーションに寄与しないことを考えると、アノテーション結果の欠如が他のキーワードの動作を間接的に変更する可能性があります。
場合によっては、キーワードの欠落しているキーワードのアサーションの振る舞いは、特定の値によって生成されるものと同じであり、キーワード定義は既知の場合にそのような値に注意する必要があります。ただし、デフォルトの振る舞いを生成する値が存在する場合にアノテーション結果を生成する場合でも、デフォルトの振る舞いはアノテーションをもたらしてはなりません。
アノテーションの収集には、計算とメモリの両方の観点から大きなコストがかかる可能性があるため、実装はこの機能をオプトアウトする場合があります。アノテーション結果に依存するアサーションまたはアプリケーターの動作を持つことが実装によって認識されているキーワードは、同じ動作を生成する代替の実装が利用可能でない限り、エラーとして扱われる必要があります。この種のキーワードは、適切な場合に適切な代替アプローチを記述する必要があります。このアプローチは、このドキュメントの「additionalItems」キーワードと「additionalProperties」キーワードで示されています。
識別子は、スキーマの正規URIを設定するか、参照でそのようなURIが解決される方法に影響を与えるか、またはその両方に影響を与えます。このドキュメントで定義されているコア語彙は、いくつかの識別キーワード、特に「$id」を定義します。
正規のスキーマURIはインスタンスの処理中に変更してはなりませんが、URI参照の解決に影響を与えるキーワードは、実行時にのみ完全に決定される動作を持つ場合があります。
カスタム識別子キーワードは可能ですが、語彙の設計者は、コアキーワードの機能を妨げないように注意する必要があります。たとえば、この仕様の「$recursiveAnchor」キーワードは、URI解決の効果を一致する「$recursiveRef」キーワードに限定し、「$ref」を邪魔しないようにします。
アプリケーターを使用すると、単一のスキーマオブジェクトでは実現できない、より複雑なスキーマを構築できます。スキーマドキュメントに対するインスタンスの評価は、ルートスキーマを完全なインスタンスドキュメントに適用することから始まります。そこから、アプリケーターとして知られるキーワードを使用して、適用される追加のスキーマを決定します。このようなスキーマは、現在の場所または子の場所にインプレースで適用できます。
適用されるスキーマは、キーワードの値の全部または一部を構成するサブスキーマとして存在する場合があります。あるいは、アプリケーターは、同じスキーマドキュメントまたは別のスキーマドキュメント内の別の場所にあるスキーマを参照する場合があります。このような参照スキーマを識別するためのメカニズムは、キーワードによって定義されます。
アプリケーターキーワードは、サブスキーマまたは参照スキーマのブール値のアサーション結果が、アプリケーターのブール値の結果を生成するためにどのように変更または結合されるかを定義します。アプリケーターは、サブスキーマのアサーション結果に任意のブール論理演算を適用できますが、独自のアサーション条件を導入してはなりません。
アノテーションの結果は、各アノテーションキーワードによって指定されたルールに従って結合されます。
セクション7.5で述べたように、アプリケーターキーワードは、アプリケーターの値にサブスキーマとして含めるのではなく、適用されるスキーマを参照する場合があります。このような状況では、適用されるスキーマは参照スキーマとして知られており、アプリケーターキーワードを含むスキーマは参照元スキーマです。
ルートスキーマとサブスキーマは、スキーマドキュメント内のスキーマの位置に基づく静的な概念ですが、参照スキーマと参照元スキーマは動的です。スキーマの異なるペアは、スキーマに対するインスタンスの評価中に、さまざまな参照および参照配置になる可能性があります。
「$ref」など、一部のby-referenceアプリケーターでは、参照スキーマはスキーマドキュメントの字句スコープの静的分析によって決定できます。それ以外に、「$recursiveRef」や「$recursiveAnchor」などは、動的スコープを使用する場合があり、したがって、インスタンスを使用してスキーマを評価するプロセスでのみ解決可能です。
JSON Schemaは、JSONドキュメントに制約をアサートするために使用でき、アサーションに合格または失敗します。このアプローチは、制約への適合性を検証したり、制約を満たすために必要なものを文書化するために使用できます。
JSON Schema実装は、スキーマアサーションに対してインスタンスを評価するときに、単一のブール結果を生成します。
インスタンスは、スキーマに存在するアサーションにのみ失敗する可能性があります。
ほとんどのアサーションは、特定のプリミティブ型内の値のみを制約します。インスタンスの型がキーワードのターゲットとする型でない場合、インスタンスはアサーションに準拠すると見なされます。
たとえば、コンパニオンの検証語彙の「maxLength」キーワードは、(長すぎる)特定の文字列のみが有効になるのを制限します。インスタンスが数値、ブール値、null、配列、またはオブジェクトの場合、このアサーションに対して有効です。
この動作により、複数のプリミティブ型になる可能性のあるインスタンスでキーワードをより簡単に使用できます。コンパニオンの検証語彙には、インスタンスを1つまたは複数のプリミティブ型に個別に制限できる「type」キーワードも含まれています。これにより、特定の長さの文字列またはnull値を返す可能性のある関数などのユースケースを簡潔に表現できます。
{ "type": ["string", "null"], "maxLength": 255 }
「maxLength」がインスタンス型を文字列に制限した場合、記述された例ではnull値を実際に許可しないため、これを表現するのは大幅に面倒になります。特に指定がない限り、各キーワードは個別に評価されるため、「maxLength」がインスタンスを文字列に制限した場合、「type」に「null」を含めても役に立ちません。
JSON Schemaは、インスタンスがアノテーションを含むスキーマオブジェクト、およびそのすべての親スキーマオブジェクトに対して検証されるたびに、インスタンスに情報をアノテーションすることができます。情報は、単純な値である場合も、インスタンスの内容に基づいて計算される場合もあります。
アノテーションは、インスタンス内の特定の場所に取り付けられます。多くのサブスキーマが単一の場所に適用できるため、アノテーションキーワードは、異なる値を持つキーワードの複数回適用に対する異常な処理を指定する必要があります。
アサーションの結果とは異なり、アノテーションデータはさまざまな形式をとることができ、アプリケーションが適切と見なすように使用するために提供されます。JSON Schema実装は、アプリケーションに代わって収集された情報を使用することは期待されていません。
特に明記しない限り、アノテーションキーワードのアノテーションの値は、そのキーワードの値となります。ただし、他の動作も可能です。例えば、JSON Hyper-Schemaの "links" キーワードは、インスタンスデータの一部に基づいて値を生成する複雑なアノテーションです。
アサーションには「ショートサーキット」評価が可能ですが、アノテーションの収集には、たとえ全体的なアサーションの結果を変更できない場合でも、インスタンスの位置に適用されるすべてのスキーマを調べる必要があります。唯一の例外は、検証に失敗したスキーマオブジェクトのサブスキーマは、アノテーションが失敗したスキーマでは保持されないため、スキップしてもよいということです。
アノテーションは、アノテーション収集の動作を明示的に定義するキーワードによって収集されます。ブールスキーマはキーワードを使用しないため、アノテーションを生成できないことに注意してください。
収集されたアノテーションには、次の情報を含める必要があります。
同じキーワードが複数のスキーマの場所から同じインスタンスの場所に値を添付し、アノテーションがそのような値を結合するためのプロセスを定義する場合、結合された値もインスタンスの場所に関連付けられている必要があります。この仕様で説明されているアノテーション情報を含む出力形式はこの要件を満たしています。
アプリケーションは、値を提供したスキーマの場所に基づいて、複数のアノテーション値のうちどれを使用するかを決定できます。これは柔軟な使用を可能にすることを目的としています。スキーマの場所を収集することで、このような使用が容易になります。
たとえば、検証仕様のアノテーションとアサーションを使用する次のスキーマを考えてみましょう。
明確にするために、一部の行は折り返されています。
{ "title": "Feature list", "type": "array", "items": [ { "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つの異なる値が存在することをエラーと見なす場合があります。
falseのアサーション結果を生成するスキーマオブジェクトは、自身またはサブスキーマのキーワードに関係なく、アノテーション結果を生成してはなりません。
ただし、全体的なスキーマの結果には、他のスキーマの場所から収集されたアノテーションが含まれる可能性があります。次のスキーマを考えます。
{ "oneOf": [ { "title": "Integer Value", "type": "integer" }, { "title": "String Value", "type": "string" } ] }
インスタンス"This is a string"の場合、そのスキーマオブジェクトの型アサーションが失敗したため、「Integer Value」というタイトルのアノテーションは破棄されます。インスタンスが文字列型のアサーションに合格しているため、「String Value」というタイトルのアノテーションは保持されます。
アプリケータキーワードは、独自のアノテーション結果を定義する可能性に加えて、サブスキーマまたは参照スキーマで収集されたアノテーションを集約します。アノテーション値を集約するための規則は、各アノテーションキーワードによって定義され、アサーション結果を組み合わせるために使用されるロジックに直接影響されません。
4番目のカテゴリのキーワードは、再利用可能なコンポーネントまたはスキーマ作成者が関心のある、再利用には適さないデータを保持するための場所を予約するだけです。これらのキーワードは、検証またはアノテーションの結果に影響しません。コア語彙でのこれらのキーワードの目的は、特定の目的に場所が利用可能であり、拡張キーワードによって再定義されないようにすることです。
これらのキーワードは結果に直接影響を与えませんが、セクション8.2.4.4で説明されているように、再利用可能なスキーマの場所を予約する認識されない拡張キーワードは、特定の状況で参照との望ましくない相互作用を引き起こす可能性があります。
このセクションで宣言された、すべて "$" で始まるキーワードは、JSONスキーマコア語彙を構成します。これらのキーワードは、複数のドキュメントに分割されたものを含む、スキーマまたはメタスキーマを処理するために必須であるか、相互運用性を保証する必要がある目的のためにキーワードを予約するために存在します。
コア語彙は、さらなる語彙の処理をブートストラップするために、常に必須であると見なす必要があります。"$vocabulary"キーワードを使用して使用中の語彙を宣言するメタスキーマは、必須であることを示すtrueの値を持つコア語彙を明示的にリストする必要があります。
この語彙(およびこの語彙のみ)のfalse値の動作は未定義であり、"$vocabulary"が存在するがコア語彙が含まれていない場合の動作も同様です。ただし、実装ではこれらのケースを検出し、発生したときにエラーを発生させることが推奨されます。メタスキーマがコアをオプションで使用すると宣言することは意味がありません。
"$vocabulary"を使用しないメタスキーマは、URIがtrueの値で存在する場合と同様に、コア語彙を必須とするものと見なす必要があります。
コア語彙の現在のURIは次のとおりです:<https://json-schema.dokyumento.jp/draft/2019-09/vocab/core>。
対応するメタスキーマの現在のURIは次のとおりです:<https://json-schema.dokyumento.jp/draft/2019-09/meta/core>。
"$"プレフィックスは正式にはコア語彙用に予約されていませんが、拡張キーワード(語彙やその他のキーワード)は、将来の衝突の可能性を回避するために、"$"以外の文字で始めることをお勧めします。
実装にスキーマを解釈する方法を通知するために、メタスキーマと語彙の2つの概念が使用されます。すべてのスキーマにはメタスキーマがあり、"$schema"キーワードを使用して宣言できます。
メタスキーマには2つの目的があります。
メタスキーマは語彙とは別に、語彙をさまざまな方法で組み合わせたり、メタスキーマ作成者が特定のキーワードを禁止したり、開発およびテストサイクル中に行われるように、非常に厳格な構文検証を実行するなど、追加の制約を課すことができるようにします。通常、各語彙は、語彙のキーワードのみで構成されるメタスキーマを識別します。
メタスキーマの作成はJSONスキーマの高度な使用法であるため、メタスキーマ機能の設計はシンプルさよりも柔軟性を重視しています。
"$schema"キーワードは、JSONスキーマの機能セット識別子としても、この特定の機能セット用に記述された有効なスキーマのセットを記述するJSONスキーマ自体であるリソースの識別子としても使用されます。
このキーワードの値はURI(スキームを含む)でなければならず、このURIは正規化されている必要があります。現在のスキーマは、このURIで識別されるメタスキーマに対して有効である必要があります。
このURIが取得可能なリソースを識別する場合、そのリソースはメディアタイプ "application/schema+json"である必要があります。
"$schema"キーワードは、リソースのルートスキーマで使用する必要があります。リソースのサブスキーマに表示してはなりません。ルートスキーマにない場合、結果の動作は実装定義です。
単一のドキュメントに複数のスキーマリソースが存在する場合、すべてのスキーマリソースは、"$schema"に対して同じ値を持つ必要があります。同じスキーマドキュメント内の"$schema"の値が異なる場合の結果は、実装定義です。 [CREF2]同じドキュメントで複数の"$schema"キーワードを使用すると、機能セット、したがって動作がドキュメント内で変更される可能性があることを意味します。これは、まだ明確に定義されていない多くの実装上の懸念事項を解決する必要があります。したがって、ルートスキーマでのみ"$schema"を使用するパターンは、スキーマ作成のベストプラクティスである可能性が高いですが、実装の動作は将来のドラフトで改訂または自由化される可能性があります。 [CREF3]埋め込みスキーマリソースの例外は、この仕様で後述するように、複数のスキーマリソースをコンテンツを変更せずに単一のスキーマドキュメントにバンドルできるようにするためです。
このプロパティの値は、このドキュメントおよび他のドキュメント、および他の当事者によって別途定義されます。
"$vocabulary"キーワードは、メタスキーマで、そのメタスキーマで記述されたスキーマで使用できる語彙を識別するために使用されます。また、各語彙が必須かオプションかを示すためにも使用されます。これは、実装がスキーマを正常に処理するために必須の語彙を理解する必要があるという意味です。
このキーワードの値はオブジェクトでなければなりません。オブジェクトのプロパティ名はURI(スキームを含む)でなければならず、このURIは正規化されている必要があります。プロパティ名として表示される各URIは、特定のキーワードセットとそのセマンティクスを識別します。
URIはURLである可能性がありますが、取得可能なリソースの性質は現在未定義であり、将来の使用のために予約されています。語彙の作成者は、語彙URIとして、text/htmlやtext/plainなどの人間が判読可能なメディアタイプで、語彙仕様のURLを使用できます。[CREF4]語彙ドキュメントは、今後のドラフトで追加される可能性があります。今のところ、キーワードセットを特定することで十分と見なされます。これは、メタスキーマ検証と合わせて、現在の「語彙」が機能する方法であるためです。将来の語彙ドキュメント形式はJSONドキュメントとして指定されるため、当面はtext/htmlや他の非JSON形式を使用しても、将来的な曖昧さを生じることはありません。
オブジェクトプロパティの値はブール値でなければなりません。値がtrueの場合、語彙を認識しない実装は、「$schema」でこのメタスキーマを宣言するすべてのスキーマの処理を拒否する必要があります。値がfalseの場合、語彙を認識しない実装は、そのようなスキーマの処理を続行する必要があります。
6.5に従い、認識されないキーワードは無視する必要があります。これは、認識されない語彙で定義されたキーワードについても同様です。語彙で定義されている認識されないキーワードと、どの語彙にも属さないキーワードを区別することは、現在できません。
「$vocabulary」キーワードは、メタスキーマとして使用されることを目的としたスキーマドキュメントのルートスキーマで使用する必要があります。サブスキーマには表示されてはなりません。
「$vocabulary」キーワードは、メタスキーマとして処理されていないスキーマドキュメントでは無視する必要があります。これにより、バリデーターがMによって宣言された語彙を理解する必要なく、メタスキーマMを自身のメタスキーマM'に対して検証できます。
「$vocabulary」がない場合、実装は、参照スキーマの「$schema」キーワードのURI値から認識される場合、メタスキーマに基づいて動作を決定できます。これは、(Hyper-Schemaの使用など)語彙が存在する以前に動作が認識されていた方法です。
スキーマによって参照されるメタスキーマが認識されない場合、または欠落している場合、動作は実装定義です。実装がスキーマの処理を続行する場合、コア語彙の使用を想定する必要があります。実装が特定の目的のために構築されている場合、その目的に関連性の高いすべての語彙の使用を想定する必要があります。
たとえば、バリデーターである実装は、この仕様と関連する検証仕様のすべての語彙の使用を想定する必要があります。
「$vocabulary」の処理制限は、「$ref」または同様のキーワードを使用して他のメタスキーマを参照するメタスキーマが、それらの他のメタスキーマの語彙宣言を自動的に継承しないことを意味することに注意してください。メタスキーマとして使用されることを目的とした各スキーマドキュメントのルートで、そのような宣言をすべて繰り返す必要があります。これは、メタスキーマの例で示されています。[CREF5]この要件により、実装は各メタスキーマの1か所ですべての語彙要件情報を見つけることができます。スキーマの拡張性とは、より細粒度のメタスキーマを参照によって組み合わせるための無限の可能性があることを意味するため、実装がすべての可能性を予測し、参照されるメタスキーマで語彙を検索することを要求することは、過度に負担になるでしょう。
エラーを修正するために、仕様ドラフト間で更新された語彙およびメタスキーマURIが公開される場合があります。実装は、この仕様ドラフト以降、次のドラフトまでの日付のURIが、ここにリストされているものと同じ構文とセマンティクスを示すと見なす必要があります。
実装は、別のスキーマの「$schema」キーワードによってメタスキーマとして識別されたために検査されている場合、スキーマをメタスキーマとして認識する必要があります。これは、単一のスキーマドキュメントが、通常のスキーマと見なされることもあれば、メタスキーマと見なされることもあることを意味します。
自身のメタスキーマであるスキーマを検査する場合、実装が通常のスキーマとして処理を開始すると、その規則の下で処理されます。ただし、自身の「$schema」値をチェックした結果として2回目にロードされた場合、メタスキーマとして扱われます。したがって、同じドキュメントが1つのセッション中に両方の方法で処理されます。
実装は、実装固有の目的のために、たとえば、一般的に使用されるメタスキーマをプリロードし、その語彙サポート要件を事前にチェックするために、スキーマをメタスキーマとして明示的に渡すことを許可する場合があります。メタスキーマの作成者は、そのような機能が実装間で相互運用可能であることを期待してはなりません。
広大なエコシステムでスキーマを区別するために、スキーマはURIによって識別され、URIを指定することで他のスキーマへの参照を埋め込むことができます。
いくつかのキーワードは、相対URI参照、または相対URI参照を構築するために使用される値を受け入れることができます。これらのキーワードでは、参照を解決するためにベースURIを確立する必要があります。
RFC3986セクション5.1は、ドキュメントのデフォルトベースURIを決定する方法を定義しています。
参考までに、スキーマの初期ベースURIは、ネットワークロケーション、ローカルファイルシステム、または既知のスキームのURIで識別可能なその他の状況であるかどうかにかかわらず、スキーマが見つかったURIです。
スキーマドキュメントが「$id」(コンテンツに埋め込まれています)で明示的なベースURIを定義していない場合、ベースURIはRFC 3986セクション5に従って決定されます。
ソースが不明な場合、またはソースに既知のURIスキームがない場合、RFC 3986セクション5.1.4で説明されているように、適切な実装固有のデフォルトURIを使用できます。実装が想定するデフォルトベースURIを文書化することをお勧めします。
次のセクションで説明する「$id」キーワードがルートスキーマに存在しない限り、このベースURIは、スキーマドキュメントのルートスキーマリソースの正規URIと見なされる必要があります。
「$id」キーワードは、正規URIを持つスキーマ リソースを識別します。
このURIは識別子であり、必ずしもネットワークロケーターではないことに注意してください。ネットワークアドレス指定可能なURLの場合、スキーマは正規URIからダウンロード可能である必要はありません。
存在する場合、このキーワードの値は文字列である必要があり、有効なURI参照を表す必要があります。このURI参照は正規化される必要があり、絶対URI(フラグメントなし)に解決される必要があります。したがって、「$id」には空でないフラグメントを含めることはできず、空のフラグメントを含めることはできません。
application/schema+jsonメディアタイプのコンテキストでの空のフラグメントは、フラグメントのないベースURIと同じリソースを参照するため、実装は、空のフラグメントで終わるURIをフラグメントを削除することによって正規化できます。ただし、スキーマ作成者は、実装間でこの動作に依存しないでください。[CREF6]これは主に、古いメタスキーマが$id(または以前はid)に空のフラグメントを持っているために許可されています。将来のドラフトでは、$idで空のフラグメントさえも完全に禁止される可能性があります。
このURIは、コンテンツに埋め込まれたベースURIに関するRFC 3986セクション5.1.1に従って、スキーマリソース内のキーワードの相対URI参照のベースURIとしても機能します。
サブスキーマに「$id」が存在することは、サブスキーマが単一のスキーマドキュメント内で個別のスキーマ リソースを構成することを示します。さらに、エンティティのカプセル化に関するRFC 3986セクション5.1.2に従い、サブスキーマの「$id」が相対URI参照の場合、その参照を解決するためのベースURIは、親スキーマ リソースのURIです。
親スキーマオブジェクトが「$id」でリソースとして自身を明示的に識別しない場合、ベースURIは、前のセクションで説明した手順で確立された、ドキュメント全体のベースURIです。
JSONスキーマドキュメントのルートスキーマには、絶対URI(スキームは含むが、フラグメントは含まない)を持つ「$id」キーワードを含める必要があります。
JSONポインターURIフラグメントは、スキーマドキュメントの構造に基づいて構築されるため、埋め込まれたスキーマリソースとそのサブスキーマは、自身の正規URI、または含まれるリソースのURIのいずれかに対する相対的なJSONポインターフラグメントによって識別できます。
概念的には、リンクされたスキーマリソースのセットは、各リソースがスキーマ参照で接続された個別のドキュメントであるか、1つ以上のスキーマリソースがサブスキーマとして埋め込まれた単一のドキュメントとして構造化されているかに関係なく、同じように動作する必要があります。
親スキーマリソースのURIに対する相対的なJSONポインターフラグメントを含むURIは、埋め込まれたスキーマが別のドキュメントに移動されて参照されると無効になるため、アプリケーションとスキーマは、埋め込まれたスキーマリソースまたはその中の場所を識別するためにそのようなURIを使用しないでください。
内部に別のスキーマリソースが埋め込まれた次のスキーマドキュメントを考えてみましょう。
{ "$id": "https://example.com/foo", "items": { "$id": "https://example.com/bar", "additionalProperties": { } } }
URI "https://example.com/foo#/items/additionalProperties" は、埋め込まれたリソースの "additionalProperties" キーワードのスキーマを指します。ただし、そのスキーマの正規URIは、"https://example.com/bar#/additionalProperties" です。
ここで、「$ref」のURI値を使用して参照によってリンクされた次の2つのスキーマリソースを考えてみましょう。
{ "$id": "https://example.com/foo", "items": { "$ref": "bar" } } { "$id": "https://example.com/bar", "additionalProperties": { } }
ここでは、「additionalProperties」サブスキーマの正規URIが依然として有効である一方で、「#/items/$ref」で始まるフラグメントを持つ非正規URIは何も解決しないことがわかります。
また、「https://example.com/foo#/items」は両方の配置で有効ですが、異なる値を解決することにも注意してください。このURIは、リソースの取得URIと同様に機能します。有効ですが、解決された値を調べ、(値がサブスキーマの場合は)「$id」を使用するか、参照を解決して参照ターゲットの「$id」を使用する方が望ましいです。
実装は、非正規の URI によるスキーマのアドレス指定をサポートしないことを選択できます。そのため、スキーマの相互運用性を低下させる可能性があるため、スキーマ作成者は正規の URI のみを使用することが推奨されます。 [CREF7]これは、スキーマ リソースが再編成された場合、すべてが脆弱になるため、実装が可能なすべてのベース URI と JSON ポインター フラグメントのスタック全体を追跡する必要がないようにするためです。これを簡単だから禁止する意味がないと主張する人もいれば、スキーマの識別を複雑にするため禁止すべきだと主張する人もいます。このトピックに関するフィードバックをお待ちしています。
このような非正規の URI の例、および代わりに使用する適切な正規の URI は、付録 A に記載されています。
JSON ポインター フラグメントを使用するには、スキーマの構造に関する知識が必要です。再利用可能なスキーマを提供する目的でスキーマ ドキュメントを作成する場合、特定の構造上の場所に結び付けられていないプレーンな名前フラグメントを使用することが望ましい場合があります。これにより、JSON ポインター参照を更新することなく、サブスキーマを再配置できます。
"$anchor" キーワードは、そのようなフラグメントを指定するために使用されます。これは、プレーンな名前フラグメントを作成するためにのみ使用できる識別子キーワードです。
存在する場合、このキーワードの値は文字列である必要があり、先頭は文字([A-Za-z])、その後に任意の数の文字、数字([0-9])、ハイフン("-")、アンダースコア("_")、コロン(":")、またはピリオド(".")が続く必要があります。 [CREF8]アンカー文字列には "#" 文字が含まれていないことに注意してください。これは URI 参照ではないためです。 "$anchor": "foo" は URI で使用するとフラグメント "#foo" になります。完全な例については下記を参照してください。
結果のフラグメントが追加されるベース URI は、前のセクションで説明したように "$id" キーワードによって決定されます。同じスキーマ ドキュメント内の 2 つの "$anchor" キーワードは、結果の完全な URI が異なる場合は、同じ値を持つ場合があります。ただし、同じ値とベース URI を持つ 2 つの "$anchor" キーワードの効果は未定義です。実装は、そのような使用法が検出された場合、エラーを発生させる可能性があります。
現在のインスタンスの場所に適用されるスキーマを参照するために、いくつかのキーワードを使用できます。 "$ref" と "$recursiveRef" は、参照されたスキーマをインスタンスに適用するアプリケーター キーワードです。 "$recursiveAnchor" は、"$recursiveRef" の URI 参照値の解決のためのベース URI を制御する識別子キーワードです。
"$ref" と "$recursiveRef" の値は URI 参照であるため、スキーマを複数のファイルに外部化または分割することができ、自己参照を通じて再帰的な構造を検証する機能を提供します。
これらのキーワードによって生成された解決済みの URI は、必ずしもネットワーク ロケーターではなく、単なる識別子です。ネットワーク アドレス指定可能な URL の場合でも、スキーマをアドレスからダウンロードする必要はなく、実装は、ネットワーク アドレス指定可能な URI が検出されたときにネットワーク操作を実行する必要があると想定しないでください。
"$ref" キーワードは、静的に識別されたスキーマを参照するために使用されるアプリケーターです。その結果は、参照されたスキーマの結果です。 [CREF9]結果がどのように決定されるかのこの定義は、同じスキーマ オブジェクト内で "$ref" と並んで他のキーワードが表示される可能性があることを意味します。
"$ref" プロパティの値は、URI 参照である文字列である必要があります。現在の URI ベースに対して解決され、適用するスキーマの URI が生成されます。
"$recursiveRef" と "$recursiveAnchor" キーワードは、拡張可能な再帰的スキーマを構築するために使用されます。再帰的スキーマとは、空のフラグメント URI 参照("#")によって識別される独自のルートへの参照を持つスキーマです。
簡単に言えば、"$recursiveRef" は、ターゲット スキーマに値が true の "$recursiveAnchor" が含まれている場合を除き、"$ref" と同じように動作します。その場合、新しいベース URI を決定するために動的スコープが調べられ、"$recursiveRef" の URI 参照がそのベース URI に対して再評価されます。"$id" によるベース URI の変更とは異なり、"$recursiveAnchor" による変更は、"$recursiveRef" が解決されるたびに計算され、他のキーワードには影響しません。
これらのキーワードを使用した例については、付録 C を参照してください。 [CREF10]以前のドラフトのハイパースキーマ メタスキーマとこのドラフトの違いは、これらのキーワードの有用性を劇的に示しています。
"$recursiveRef" プロパティの値は、URI 参照である文字列である必要があります。これは、動的に計算されたベース URI を使用して値を解決する参照によるアプリケーターです。
このキーワードの動作は、値 "#" に対してのみ定義されています。実装は、他の値をエラーと見なすことを選択できます。 [CREF11]この制限は将来緩和される可能性がありますが、現在までに値 "#" だけが明確なユースケースを持っています。
"$recursiveRef" の値は、最初に "$ref" の場合と同じように、現在のベース URI に対して解決されます。
結果の URI によって識別されるスキーマには "$recursiveAnchor" の存在が調べられ、次のセクションでそのキーワードについて説明されているように、新しいベース URI が計算されます。
最後に、"$recursiveRef" の値は、"$recursiveAnchor" に従って決定された新しいベース URI に対して解決され、最終的な解決済み参照 URI が生成されます。
"$recursiveAnchor" がない場合(および存在する場合もあります)は、"$recursiveRef" の動作は "$ref" の動作と同一であることに注意してください。
"$ref" の場合と同様に、このキーワードの結果は、参照されたスキーマの結果です。
"$recursiveAnchor" プロパティの値は、ブール値である必要があります。
"$recursiveAnchor" は、そのような計算を開始および停止できる場所をマークすることにより、"$recursiveRef" の実行時にベース URI を動的に識別するために使用されます。このキーワードは、明示的にそれに依存するように定義されていない限り、他のキーワードのベース URI に影響を与えてはなりません。
true に設定されている場合、"$recursiveRef" のターゲットとして含まれているスキーマ オブジェクトが使用されると、値が true の "$recursiveAnchor" も含む最も外側のスキーマの動的スコープを調べることにより、新しいベース URI が決定されます。そのスキーマのベース URI が、動的なベース URI として使用されます。
そのようなスキーマが存在しない場合、ベース URI は変更されません。
このキーワードが false に設定されている場合、ベース URI は変更されません。
このキーワードを省略すると、値が false の場合と同じ動作になります。
スキーマは、インスタンスに対して無限ループに陥ってはなりません。たとえば、2 つのスキーマ "#alice" と "#bob" の両方に、もう一方を参照する "allOf" プロパティがある場合、単純なバリデーターは、インスタンスを検証しようとして無限再帰ループにスタックする可能性があります。スキーマは、このような無限の再帰的なネストを使用しないでください。動作は未定義です。
サブスキーマ オブジェクト(またはブール値)は、既知のアプリケーター キーワード、または値として 1 つ以上のサブスキーマを取る "$defs" などのロケーション予約キーワードでの使用によって認識されます。これらのキーワードは、"$defs" およびこのドキュメントの標準アプリケーター、既知の語彙の拡張キーワード、または実装固有のカスタム キーワードである場合があります。
未知のキーワードの多層構造は、ネストされたサブスキーマを導入する可能性があり、これは "$id" の処理規則に従います。したがって、そのような認識されない構造で参照ターゲットを持つことは確実に実装できず、結果の動作は未定義です。同様に、値がスキーマではないことがわかっている既知のキーワードの下の参照ターゲットは、そのようなターゲットを検出する必要性を実装に負担をかけないために、未定義の動作をもたらします。 [CREF12]これらのシナリオは、HTTP 経由でスキーマをフェッチしても、Content-Type が application/schema+json ではない応答を受信する場合に似ています。実装は確かにそれをスキーマとして解釈しようとすることができますが、オリジンサーバーは実際にはそのようなものであるという保証を提供しませんでした。したがって、それをそのようなものとして解釈することにはセキュリティ上の影響があり、予測不可能な結果が生じる可能性があります。
"$defs" と同じ構文とセマンティクスを持つ単一レベルのカスタム キーワードでは、介在する "$id" キーワードを使用できないため、任意の参照ターゲットをスキーマとして使用しようとする実装では正しく動作します。ただし、この動作は実装固有であり、相互運用性のために依存してはなりません。
リモート スキーマを識別するために URI を使用することは、必ずしも何もダウンロードされないことを意味するのではなく、JSON スキーマの実装は、使用するスキーマとそれらを識別する URI を事前に理解しておく必要があります。
ダウンロードするスキーマを実行時までわからない汎用ユーザーエージェントなどがスキーマをダウンロードする場合は、「ハイパーメディアでの使用」を参照してください。
実装は、バリデーターがスキーマを信頼しているかどうかに応じて、任意の URI を任意のスキーマに関連付けたり、スキーマの "$id" で指定された URI を自動的に関連付けたりできる必要があります。このような URI とスキーマは、インスタンスを処理する前に実装に提供するか、処理中にスキーマ ドキュメント内に記述して、付録 A に示すような関連付けを生成することができます。
スキーマには複数の URI がある(可能性が高い)可能性がありますが、1 つの URI が複数のスキーマを識別する方法はありません。複数のスキーマが同じ URI として識別しようとすると、バリデーターはエラー状態を発生させる必要があります。
スキーマは、JSON ポインターや "$id" によって直接指定された URI など、与えられた任意の URI によって識別できます。いずれの場合も、"$ref" 参照をデリファレンスするには、最初に RFC 3986 に従って、現在のベース 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 に対して "$id" URI 参照を解決して、<https://example.net/root.json#item> を形成します。
実装が次に <#/items> スキーマ内を調べると、<#item> 参照が検出され、これが <https://example.net/root.json#item> に解決されます。これは同じドキュメント内で定義されていることが確認されており、したがって自動的に使用できます。
実装が「other.json」への参照を検出した場合、これは<https://example.net/other.json>に解決されますが、このドキュメントでは定義されていません。その識別子を持つスキーマが実装に別途提供されている場合、自動的に使用することもできます。[CREF13]参照されたスキーマが不明な場合、実装は何をすべきでしょうか? 自動的なネットワーク逆参照が許可される状況はありますか? 同一オリジンポリシーは? ユーザー設定可能なオプションは? Hyper-Schemaで記述された進化するAPIの場合、新しいスキーマがシステムに動的に追加されることが想定されるため、スキーマドキュメントの事前ロードの絶対要件を設けることは実現可能ではありません。
"$defs" キーワードは、スキーマ作成者が再利用可能な JSON スキーマをより一般的なスキーマにインライン化するための場所を予約します。このキーワードは、検証結果に直接影響を与えません。
このキーワードの値はオブジェクトである必要があります。このオブジェクトの各メンバーの値は、有効な JSON スキーマである必要があります。
{ "type": "array", "items": { "$ref": "#/$defs/positiveInteger" }, "$defs": { "positiveInteger": { "type": "integer", "exclusiveMinimum": 0 } } }
例として、正の整数の配列を記述するスキーマを以下に示します。ここで、正の整数の制約は "$defs" 内のサブスキーマです。
このキーワードは、スキーマ作成者からスキーマの読者またはメンテナーへのコメントの場所を予約します。
このキーワードの値は文字列である必要があります。実装は、この文字列をエンドユーザーに提示してはなりません。スキーマを編集するためのツールは、このキーワードの表示と編集をサポートする必要があります。このキーワードの値は、スキーマを使用する開発者向けのデバッグまたはエラー出力で使用できます。
スキーマ語彙は、語彙キーワードを含む任意のオブジェクト内で "$comment" を許可する必要があります。実装は、語彙が明示的に禁止しない限り、"$comment" が許可されていると想定できます。語彙は、この仕様で説明されている範囲を超えて "$comment" の効果を指定してはなりません。
他のメディアタイプまたはプログラミング言語を application/schema+json との間で変換するツールは、そのメディアタイプまたはプログラミング言語のネイティブコメントを "$comment" 値との間で変換することを選択できます。ネイティブコメントと "$comment" プロパティの両方が存在する場合のそのような変換の動作は、実装に依存します。
実装は、"$comment" を不明な拡張キーワードと同一に扱う必要があります。実装は、処理中の任意の時点で "$comment" の値を削除できます。特に、これにより、展開されたスキーマのサイズが懸念される場合に、スキーマを短縮できます。
実装は、"$comment" プロパティの有無、または内容に基づいて他のアクションを実行してはなりません。特に、"$comment" の値は、アノテーション結果として収集してはなりません。
このセクションでは、他の語彙の基礎として使用することが推奨されるアプリケーターキーワードの語彙を定義します。
「$vocabulary」を使用しないメタスキーマは、そのURIがtrueの値で存在する場合と同様に、この語彙を必要とすると見なされるべきです。
アプリケーター語彙として知られるこの語彙の現在のURIは、<https://json-schema.dokyumento.jp/draft/2019-09/vocab/applicator>です。
対応するメタスキーマの現在のURIは、<https://json-schema.dokyumento.jp/draft/2019-09/meta/applicator>です。
エラーを修正するために、仕様ドラフト間で更新された語彙およびメタスキーマURIが公開される場合があります。実装は、この仕様ドラフト以降、次のドラフトまでの日付のURIが、ここにリストされているものと同じ構文とセマンティクスを示すと見なす必要があります。
スキーマキーワードは通常、互いの結果に影響を与えることなく、独立して動作します。
スキーマ作成者の便宜のために、この語彙のキーワードにはいくつかの例外があります
これらのキーワードは、親スキーマが適用されているインスタンスの同じ場所に対してサブスキーマを適用します。これにより、さまざまな方法でサブスキーマの結果を結合または変更できます。
これらのキーワードは、サブスキーマのブールアサーション結果を結合または変更するための論理演算子に対応します。これらはアノテーション収集に直接的な影響を与えませんが、同じアノテーションキーワードを異なる値でインスタンスの場所に適用できるようにします。アノテーションキーワードは、そのような値を結合するための独自のルールを定義します。
このキーワードの値は、空でない配列である必要があります。配列の各項目は、有効なJSONスキーマである必要があります。
インスタンスは、このキーワードの値で定義されたすべてのスキーマに対して正常に検証された場合、このキーワードに対して正常に検証されます。
このキーワードの値は、空でない配列である必要があります。配列の各項目は、有効なJSONスキーマである必要があります。
インスタンスは、このキーワードの値で定義された少なくとも1つのスキーマに対して正常に検証された場合、このキーワードに対して正常に検証されます。アノテーションが収集されている場合は、正常に検証される各サブスキーマからアノテーションが収集されるように、すべてのサブスキーマを調べる必要があることに注意してください。
このキーワードの値は、空でない配列である必要があります。配列の各項目は、有効なJSONスキーマである必要があります。
インスタンスは、このキーワードの値で定義された正確に1つのスキーマに対して正常に検証された場合、このキーワードに対して正常に検証されます。
このキーワードの値は、有効な JSON スキーマである必要があります。
インスタンスは、このキーワードで定義されたスキーマに対して正常に検証できなかった場合、このキーワードに対して有効です。
これらのキーワードのうち3つは、別のサブスキーマの結果に基づいてサブスキーマの条件付き適用を実装するために連携して動作します。4番目は、特定の条件付きケースのショートカットです。
"if"、"then"、および "else" は、サブスキーマの境界を越えて相互にやり取りしてはなりません。言い換えれば、"allOf" のあるブランチの "if" は、別のブランチの "then" または "else" に影響を与えてはなりません。
"if"、"then"、または "else" が存在しない場合、デフォルトの動作はありません。特に、空のスキーマが存在する場合のように扱ってはならず、"if" が存在しない場合は、"then" と "else" の両方を完全に無視する必要があります。
このキーワードの値は、有効な JSON スキーマである必要があります。
このキーワードのサブスキーマの検証結果は、全体的な検証結果に直接影響を与えません。むしろ、"then" または "else" キーワードのどちらが評価されるかを制御します。
このキーワードのサブスキーマに対して正常に検証されたインスタンスは、存在する場合は "then" キーワードのサブスキーマ値に対しても有効である必要があります。
このキーワードのサブスキーマに対して検証に失敗したインスタンスは、存在する場合は "else" キーワードのサブスキーマ値に対しても有効である必要があります。
アノテーションが収集されている場合、キーワードが "then" または "else" のいずれもなしで存在する場合を含め、通常の方法でこのキーワードのサブスキーマから収集されます。
このキーワードの値は、有効な JSON スキーマである必要があります。
"if" が存在し、インスタンスがそのサブスキーマに対して正常に検証された場合、インスタンスがこのキーワードのサブスキーマに対しても正常に検証された場合、このキーワードに対する検証は成功します。
このキーワードは、"if" が存在しない場合、またはインスタンスがそのサブスキーマに対して検証に失敗した場合には効果がありません。実装は、そのような場合、検証またはアノテーション収集の目的で、このキーワードに対してインスタンスを評価してはなりません。
このキーワードの値は、有効な JSON スキーマである必要があります。
"if" が存在し、インスタンスがそのサブスキーマに対して検証に失敗した場合、インスタンスがこのキーワードのサブスキーマに対して正常に検証された場合、このキーワードに対する検証は成功します。
このキーワードは、"if" が存在しない場合、またはインスタンスがそのサブスキーマに対して正常に検証された場合には効果がありません。実装は、そのような場合、検証またはアノテーション収集の目的で、このキーワードに対してインスタンスを評価してはなりません。
このキーワードは、インスタンスがオブジェクトであり、特定のプロパティを含んでいる場合に評価されるサブスキーマを指定します。
このキーワードの値はオブジェクトである必要があります。オブジェクト内の各値は、有効な JSON スキーマである必要があります。
オブジェクトキーがインスタンスのプロパティである場合、インスタンス全体がサブスキーマに対して検証される必要があります。その使用は、プロパティの存在に依存します。
このキーワードを省略することは、空のオブジェクトと同じ動作になります。
これらの各キーワードは、子インスタンス、特にオブジェクトプロパティと配列項目にサブスキーマを適用し、その結果を結合するためのルールを定義します。
"items" の値は、有効な JSON スキーマまたは有効な JSON スキーマの配列のいずれかである必要があります。
"items" がスキーマの場合、配列内のすべての要素がそのスキーマに対して正常に検証されると、検証は成功します。
"items" がスキーマの配列の場合、インスタンスの各要素が、存在する場合は同じ位置のスキーマに対して検証されると、検証は成功します。
このキーワードは、このキーワードがサブスキーマを適用した最大のインデックスであるアノテーション値を生成します。値は、"items" がスキーマである場合など、サブスキーマがインスタンスのすべてのインデックスに適用された場合は、ブール値のtrueになる場合があります。
同じインスタンスの場所に適用された複数のスキーマからの "items" キーワードのアノテーション結果は、いずれかの値が true の場合は結合結果を true に設定し、それ以外の場合は最大の数値を保持することによって結合されます。
このキーワードを省略すると、空のスキーマと同じアサーション動作になります。
"additionalItems" の値は、有効な JSON スキーマである必要があります。
このキーワードの動作は、同じスキーマオブジェクト内の "items" の存在とアノテーション結果に依存します。"items" が存在し、そのアノテーション結果が数値である場合、その数値より大きいインデックスのすべてのインスタンス要素が "additionalItems" に対して検証されると、検証は成功します。
それ以外の場合、"items" が存在しないか、そのアノテーション結果がブール値の true である場合、"additionalItems" は無視する必要があります。
"additionalItems" サブスキーマがインスタンス配列内の任意の位置に適用された場合、"items" の単一スキーマの動作と同様に、ブール値の true のアノテーション結果が生成されます。同じインスタンスの場所に適用された任意のサブスキーマからの任意の "additionalItems" キーワードが true のアノテーション値を生成した場合、これらのキーワードからの結合結果も true になります。
このキーワードを省略すると、空のスキーマと同じアサーション動作になります。
実装は、"items" 配列の存在とサイズを直接確認するなど、同じ効果を生み出す別の方法でこのキーワードを実装または最適化することを選択できます。アノテーション収集をサポートしていない実装は、そうする必要があります。
"unevaluatedItems" の値は、有効な JSON スキーマである必要があります。
このキーワードの挙動は、検証対象のインスタンスの場所に適用される隣接するキーワードのアノテーション結果に依存します。具体的には、「items」および「additionalItems」のアノテーションが、「unevaluatedItems」キーワードに隣接している場合に、これらのキーワードから得られます。これらの2つのアノテーションに加えて、「unevaluatedItems」は、隣接するすべてのインプレースアプリケーターキーワードからも結果として得られます。これには、このドキュメントで定義されているインプレースアプリケーターが含まれますが、これらに限定されません。
「items」アノテーションが存在し、そのアノテーション結果が数値であり、「additionalItems」または「unevaluatedItems」アノテーションが存在しない場合、「items」アノテーションよりも大きいインデックスを持つすべてのインスタンス要素が「unevaluatedItems」に対して検証されると、検証は成功します。
それ以外の場合、「items」、「additionalItems」、または「unevaluatedItems」アノテーションのいずれかがブール値trueである場合、「unevaluatedItems」は無視されなければなりません。ただし、これらのアノテーションが存在しない場合、「unevaluatedItems」は配列内のすべての場所に適用されなければなりません。
これは、「items」、「additionalItems」、およびすべてのインプレースアプリケーターが、このキーワードが評価される前に評価されなければならないことを意味します。拡張キーワードの作成者は、このキーワードより前に評価する必要があるインプレースアプリケーターを定義してはなりません。
「unevaluatedItems」サブスキーマがインスタンス配列内の任意の場所に適用される場合、これは「items」の単一スキーマの動作と同様に、ブール値trueのアノテーション結果を生成します。同じインスタンスの場所に適用された任意のサブスキーマの「unevaluatedItems」キーワードがtrueのアノテーション値を生成する場合、これらのキーワードからの結合結果もtrueになります。
このキーワードを省略すると、空のスキーマと同じアサーション動作になります。
アノテーションを収集しない実装は、このキーワードに遭遇した際にエラーを発生させなければなりません。
このキーワードの値は、有効なJSONスキーマでなければなりません。
配列インスタンスは、少なくとも1つの要素が指定されたスキーマに対して有効である場合、「contains」に対して有効です。アノテーションを収集する場合、最初のマッチが見つかった後でも、すべての可能なアノテーションを収集するために、サブスキーマをすべての配列要素に適用する必要があります。
「properties」の値はオブジェクトでなければなりません。このオブジェクトの各値は、有効なJSONスキーマでなければなりません。
インスタンスとこのキーワードの値の両方に名前が現れる場合、その名前のすべての子インスタンスが対応するスキーマに対して正常に検証されると、検証は成功します。
このキーワードのアノテーション結果は、このキーワードによってマッチングされたインスタンスプロパティ名のセットです。同じインスタンスの場所に適用された複数のスキーマの「properties」キーワードのアノテーション結果は、セットの和集合を取ることによって結合されます。
このキーワードを省略すると、空のオブジェクトと同じアサーション動作になります。
「patternProperties」の値はオブジェクトでなければなりません。このオブジェクトの各プロパティ名は、ECMA 262正規表現方言に従って、有効な正規表現であるべきです。このオブジェクトの各プロパティ値は、有効なJSONスキーマでなければなりません。
このキーワードの値のプロパティ名として現れる正規表現に一致する各インスタンス名について、その名前の子インスタンスが、一致する正規表現に対応する各スキーマに対して正常に検証されると、検証は成功します。
このキーワードのアノテーション結果は、このキーワードによってマッチングされたインスタンスプロパティ名のセットです。同じインスタンスの場所に適用された複数のスキーマの「patternProperties」キーワードのアノテーション結果は、セットの和集合を取ることによって結合されます。
このキーワードを省略すると、空のオブジェクトと同じアサーション動作になります。
「additionalProperties」の値は、有効なJSONスキーマでなければなりません。
このキーワードの挙動は、同じスキーマオブジェクト内の「properties」および「patternProperties」の存在とアノテーション結果に依存します。「additionalProperties」による検証は、「properties」または「patternProperties」のアノテーション結果に現れないインスタンス名の子値にのみ適用されます。
このようなすべてのプロパティについて、子インスタンスが「additionalProperties」スキーマに対して検証されると、検証は成功します。
このキーワードのアノテーション結果は、このキーワードのサブスキーマによって検証されたインスタンスプロパティ名のセットです。同じインスタンスの場所に適用された複数のスキーマの「additionalProperties」キーワードのアノテーション結果は、セットの和集合を取ることによって結合されます。
このキーワードを省略すると、空のスキーマと同じアサーション動作になります。
実装は、「properties」の名前と「patternProperties」のパターンをインスタンスプロパティセットに対して直接チェックするなど、同じ効果を生み出す別の方法でこのキーワードを実装または最適化することを選択できます。アノテーションの収集をサポートしていない実装は、これを行う必要があります。
「unevaluatedProperties」の値は、有効なJSONスキーマでなければなりません。
このキーワードの挙動は、検証対象のインスタンスの場所に適用される隣接するキーワードのアノテーション結果に依存します。具体的には、「properties」、「patternProperties」、および「additionalProperties」のアノテーションが、「unevaluatedProperties」キーワードに隣接している場合に、これらのキーワードから得られます。これらの3つのアノテーションに加えて、「unevaluatedProperties」は、隣接するすべてのインプレースアプリケーターキーワードからも結果として得られます。これには、このドキュメントで定義されているインプレースアプリケーターが含まれますが、これらに限定されません。
「unevaluatedProperties」による検証は、検証対象のインスタンスの場所に適用される「properties」、「patternProperties」、「additionalProperties」、または「unevaluatedProperties」のアノテーション結果に現れないインスタンス名の子値にのみ適用されます。
このようなすべてのプロパティについて、子インスタンスが「unevaluatedProperties」スキーマに対して検証されると、検証は成功します。
これは、「properties」、「patternProperties」、「additionalProperties」、およびすべてのインプレースアプリケーターが、このキーワードが評価される前に評価されなければならないことを意味します。拡張キーワードの作成者は、このキーワードより前に評価する必要があるインプレースアプリケーターを定義してはなりません。
このキーワードのアノテーション結果は、このキーワードのサブスキーマによって検証されたインスタンスプロパティ名のセットです。同じインスタンスの場所に適用された複数のスキーマの「unevaluatedProperties」キーワードのアノテーション結果は、セットの和集合を取ることによって結合されます。
このキーワードを省略すると、空のスキーマと同じアサーション動作になります。
アノテーションを収集しない実装は、このキーワードに遭遇した際にエラーを発生させなければなりません。
「propertyNames」の値は、有効なJSONスキーマでなければなりません。
インスタンスがオブジェクトである場合、このキーワードは、インスタンス内のすべてのプロパティ名が提供されたスキーマに対して検証される場合に有効です。スキーマがテストするプロパティ名は常に文字列であることに注意してください。
このキーワードを省略すると、空のスキーマと同じ動作になります。
JSONスキーマは、プラットフォームに依存しないように定義されています。そのため、プラットフォーム間の互換性を高めるために、実装は標準の検証出力形式に準拠する必要があります。このセクションでは、コンシューマーが検証結果を適切に解釈するために必要な最小限の要件について説明します。
JSONスキーマの出力は、セクション4.2.1で説明されているJSONスキーマのデータインスタンスモデルを使用して定義されています。実装は、特定の言語やプラットフォームでサポートされているように、これから逸脱してもかまいませんが、シリアライゼーションなどの手段を通じて、ここに示すJSON形式に変換できる出力を推奨します。
この仕様では、4つの出力形式を定義しています。各形式の要件については、「出力構造」セクションを参照してください。
実装は、少なくとも「フラグ」、「基本」、または「詳細」形式を提供する必要があり、「詳細」形式を提供してもかまいません。1つ以上の複雑な形式を提供する場合、必ず「フラグ」形式も提供する必要があります。実装は、サポートする形式をドキュメントで指定する必要があります。
単純な「フラグ」出力以外にも、スキーマまたはインスタンスのデバッグを支援するために追加情報が役立ちます。各サブ結果には、少なくともこのセクションに含まれる情報が含まれている必要があります。
これらのコンポーネントをすべて含む単一のオブジェクトが出力単位と見なされます。
実装は、追加情報を提供することを選択できます。
検証パスに従う検証キーワードの相対位置。値はJSONポインターとして表す必要があり、「$ref」や「$recursiveRef」などの参照によるアプリケーターを含める必要があります。
#/properties/width/$ref/minimum
このポインターは、参照によるアプリケーターキーワードが含まれているため、通常のJSONポインター処理では解決できない場合があることに注意してください。
この情報のJSONキーは「keywordLocation」です。
検証キーワードの絶対的で参照解除された位置。値は、関連するスキーマオブジェクトの正規URIを使用した絶対URIとして表す必要があり、非終端パスコンポーネントとして「$ref」や「$recursiveRef」などの参照によるアプリケーターを含めてはなりません。エラーまたはアノテーションがそのキーワード(解決できない参照など)に関するものである場合、そのようなキーワードで終わる場合があります。
https://example.com/schemas/common#/$defs/count/minimum
この情報は、相対位置に参照が含まれていない場合、またはスキーマが絶対URIを「$id」として宣言していない場合にのみ省略できます。
この情報のJSONキーは「absoluteKeywordLocation」です。
検証対象のインスタンス内のJSON値の位置。値はURIフラグメントエンコードされた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/2019-09/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つのサブスキーマをチェックする必要はありません。ロジックは単純に成功で返すことができます。
"基本" 構造は、出力ユニットのフラットなリストです。
{ "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" } ] }
"詳細" 構造はスキーマに基づいており、人間と機械の両方にとってより読みやすくなります。このように構造が整理されていると、エラー間の関連性がより明確になります。たとえば、欠落している "y" プロパティと余分な "z" プロパティが両方ともインスタンス内の同じ場所から発生しているという事実は、"基本" 構造ではすぐにはわかりません。階層構造では、相関関係がより簡単に識別できます。
次の規則が結果オブジェクトの構築を規定します。
ブランチノードには、エラーメッセージまたはアノテーションは必要ありません。
{ "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" } ] }
"詳細出力" 構造は、スキーマの構造と正確に一致する完全に実現された階層構造です。この構造は、エラーの場所が重要なフォーム生成および検証に適用されます。
この構造と "詳細" 構造の主な違いは、すべての結果が返されることです。これには、削除されるはずのサブスキーマの検証結果 (たとえば、失敗した検証のアノテーション、`not` キーワード内の成功した検証など) が含まれます。このため、各ノードには、そのノードの検証結果を示す `valid` プロパティも持たせることを推奨します。
この出力構造は非常に大きくなる可能性があるため、ここでは簡潔にするために小さな例を示します。上記の例の完全な出力構造の URI は次のとおりです: <https://json-schema.dokyumento.jp/draft/2019-09/output/verbose-example>.
// schema { "$id": "https://example.com/polygon", "$schema": "https://json-schema.dokyumento.jp/draft/2019-09/schema", "type": "object", "properties": { "validProp": true, }, "additionalProperties": false } // instance { "validProp": 5, "disallowedProp": "value" } // result { "valid": false, "keywordLocation": "#", "instanceLocation": "#", "errors": [ { "valid": true, "keywordLocation": "#/type", "instanceLocation": "#" }, { "valid": true, "keywordLocation": "#/properties", "instanceLocation": "#" }, { "valid": false, "keywordLocation": "#/additionalProperties", "instanceLocation": "#", "errors": [ { "valid": false, "keywordLocation": "#/additionalProperties", "instanceLocation": "#/disallowedProp", "error": "Additional property 'disallowedProp' found but was invalid." } ] } ] }
便宜上、JSON Schema は、実装によって生成された出力を検証するために提供されています。その URI は次のとおりです: <https://json-schema.dokyumento.jp/draft/2019-09/output/schema>.
JSON は、HTTPサーバーによる自動化されたAPIとロボットで広く採用されています。このセクションでは、メディアタイプと Webリンクをサポートするプロトコルで使用する場合に、よりRESTfulな方法でJSONドキュメントの処理を強化する方法について説明します。
スキーマによって記述されたインスタンスは、Linked Data Protocol 1.0, セクション8.1で定義されているリンク関係 "describedby" を使用して、ダウンロード可能なJSONスキーマへのリンクを提供することを推奨します。
HTTPでは、このようなリンクをLinkヘッダーを使用して任意の応答に添付できます。このようなヘッダーの例は次のようになります
Link: <https://example.com/my-hyper-schema#>; rel="describedby"
メディアタイプでは、"schema" メディアタイプパラメータを許可することができ、これによりHTTPサーバーはスキーマに基づいてContent-Typeネゴシエーションを実行できます。メディアタイプパラメータは、URIの空白区切りのリストである必要があります(つまり、相対参照は無効です)。
メディアタイプ application/schema-instance+json を使用する場合、"schema" パラメータを指定する必要があります。
メディアタイプ application/schema+json を使用する場合、"schema" パラメータを指定してもかまいません。指定する場合、"$schema" キーワードによって識別されるURIと同じURIを含める必要があり、追加のURIを含めることもできます。"$schema" URI は、メディアタイプパラメータとしての代替または追加のメタスキーマの存在に関係なく、スキーマの正準メタスキーマと見なす必要があります。
スキーマURIは不透明であり、自動的に非参照にすべきではありません。実装が提供されたスキーマのセマンティクスを理解していない場合、実装は代わりに "describedby" リンクがあればそれに従うことができ、これによりスキーマの処理方法に関する情報を提供できます。"schema" は必ずしもネットワークの場所を指しているわけではないため、ダウンロード可能なスキーマへのリンクには "describedby" 関係が使用されます。ただし、簡略化のために、スキーマの作成者は可能な限りこれらのURIを同じリソースを指すようにする必要があります。
HTTPでは、メディアタイプパラメータはContent-Typeヘッダー内に送信されます。
Content-Type: application/json; schema="https://example.com/my-hyper-schema#"
複数のスキーマは空白で区切られており、インスタンスがリストされたすべてのスキーマに準拠していることを示します
Content-Type: application/json; schema="https://example.com/alice https://example.com/bob"
メディアタイプパラメータは、HTTPのAcceptリクエストヘッダーでも使用されます
Accept: application/json; schema="https://example.com/qiang https://example.com/li", application/json; schema="https://example.com/kumar"
Content-Typeと同様に、同じ文字列内の複数のスキーマパラメータは、リストされたすべてのスキーマに準拠するインスタンスをリクエストします。
Content-Typeとは異なり、Acceptには、クライアントが複数のメディアタイプを受け入れることができることを示す複数の値を含めることができます。上記の例では、2つのメディアタイプがスキーマパラメータ値のみが異なることに注意してください。これは、識別されたスキーマの少なくとも1つに準拠する application/json 表現をリクエストします。
[CREF14]この段落では、"schema" リンク関係を登録できることを前提としています。代わりに、今のところ "tag:json-schema.org,2017:schema" のようなものを指定する必要がありますか? HTTPはLinkで "schema" を送信することもできますが、これにより、メディアタイプパラメータを完全に置き換える場合、メディアタイプのセマンティクスとContent-Typeネゴシエーションに影響を与える可能性があります。
Link: </alice>;rel="schema", </bob>;rel="schema"
ネットワーク上のハイパーメディアシステムで使用する場合、HTTPは、スキーマを配布するための一般的なプロトコルです。クライアントの誤った動作により、必要以上に頻繁にネットワーク経由でスキーマをプルすると、サーバーの管理者に問題が発生する可能性がありますが、代わりにスキーマを長期間キャッシュすることができます。
HTTPサーバーは、JSONスキーマに長期間キャッシュヘッダーを設定する必要があります。HTTPクライアントは、キャッシュヘッダーを観察し、有効期間内にドキュメントを再リクエストしないでください。分散システムでは、共有キャッシュやキャッシュプロキシを使用する必要があります。
User-Agent: product-name/5.4.1 so-cool-json-schema/1.0.2 curl/7.43.0
クライアントは、JSON Schemaの実装またはソフトウェア製品に固有のUser-Agentヘッダーを設定または先頭に追加する必要があります。シンボルは重要度の高い順にリストされているため、JSON Schemaライブラリの名前/バージョンは、より一般的なHTTPライブラリの名前(存在する場合)の前に付ける必要があります。例えば
クライアントは、サーバーオペレーターが潜在的に誤った動作をしているスクリプトの所有者に連絡できるように、"From" ヘッダーを使用してリクエストを行うことができる必要があります。
スキーマとインスタンスはどちらもJSON値です。そのため、RFC 8259で定義されているすべてのセキュリティに関する考慮事項が適用されます。
インスタンスとスキーマはどちらも、パブリックインターネットサーバーにデプロイするために、信頼できないサードパーティによって頻繁に記述されます。バリデーターは、スキーマに対する解析と検証が過度のシステムリソースを消費しないように注意する必要があります。バリデーターは、無限ループに陥ってはなりません。
サーバーは、悪意のあるパーティが、既存の "$id" または非常に類似した "$id" を持つスキーマをアップロードすることにより、既存のスキーマの機能を変更できないようにする必要があります。
個々のJSON Schema語彙は、独自のセキュリティ上の考慮事項も持っている可能性があります。詳細については、それぞれの仕様を参照してください。
スキーマの作成者は、悪意のある実装が仕様に違反してエンドユーザーに表示したり、そのような動作が予期される場合にそれらを削除できなかったりする可能性があるため、"$comment" の内容に注意する必要があります。
悪意のあるスキーマの作成者は、"$comment" 内に実行可能なコードやその他の危険なマテリアルを配置する可能性があります。実装は、"$comment" の内容に基づいて解析したり、その他のアクションを実行したりしてはなりません。
JSON Schemaの提案されたMIMEメディアタイプは、次のように定義されます
JSONスキーマ固有のメディアタイプを必要とするJSONスキーマインスタンスの提案されたMIMEメディアタイプは、以下のように定義されます。
[ecma262] | "ECMA 262仕様" |
[RFC2119] | Bradner, S., "RFCにおける要求レベルを示すためのキーワード", BCP 14, RFC 2119, DOI 10.17487/RFC2119, 1997年3月。 |
[RFC3986] | Berners-Lee, T., Fielding, R. および L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, DOI 10.17487/RFC3986, 2005年1月。 |
[RFC6839] | Hansen, T. および A. Melnikov, "追加のメディアタイプ構造化構文サフィックス", RFC 6839, DOI 10.17487/RFC6839, 2013年1月。 |
[RFC6901] | Bryan, P., Zyp, K. および M. Nottingham, "JavaScript Object Notation (JSON) ポインタ", RFC 6901, DOI 10.17487/RFC6901, 2013年4月。 |
[RFC8259] | Bray, T., "JavaScript Object Notation (JSON) データ交換形式", STD 90, RFC 8259, DOI 10.17487/RFC8259, 2017年12月。 |
[W3C.REC-ldp-20150226] | Speicher, S., Arwe, J. および A. Malhotra, "Linked Data Platform 1.0", World Wide Web Consortium Recommendation REC-ldp-20150226, 2015年2月。 |
[json-hyper-schema] | Andrews, H. および A. Wright, "JSON Hyper-Schema: JSONのハイパーメディア注釈のための語彙", Internet-Draft draft-handrews-json-schema-hyperschema-02, 2017年11月。 |
[json-schema-validation] | Wright, A., Andrews, H. および G. Luff, "JSON Schema Validation: JSONの構造検証のための語彙", Internet-Draft draft-handrews-json-schema-validation-02, 2017年11月。 |
[RFC6596] | Ohye, M. および J. Kupke, "正規リンク関係", RFC 6596, DOI 10.17487/RFC6596, 2012年4月。 |
[RFC7049] | Bormann, C. および P. Hoffman, "簡潔なバイナリオブジェクト表現 (CBOR)", RFC 7049, DOI 10.17487/RFC7049, 2013年10月。 |
[RFC7231] | Fielding, R. および J. Reschke, "Hypertext Transfer Protocol (HTTP/1.1): セマンティクスとコンテンツ", RFC 7231, DOI 10.17487/RFC7231, 2014年6月。 |
[RFC8288] | Nottingham, M., "Web Linking", RFC 8288, DOI 10.17487/RFC8288, 2017年10月。 |
[W3C.WD-fragid-best-practices-20121025] | Tennison, J., "フラグメント識別子とメディアタイプ定義のベストプラクティス", World Wide Web Consortium WD WD-fragid-best-practices-20121025, 2012年10月。 |
以下のスキーマを検討してください。ここでは、ルートスキーマとさまざまなサブスキーマの両方を識別するために "$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ポインタ(ルートスキーマに対する相対)にあるスキーマは、以下のベースURIを持ち、上記の5章および8.2.2.2章に従って、リストされている任意のURIで識別可能です。
参照 ("$ref") がどのように表示されるかに基づいて、スキーマドキュメントを再配置するために、さまざまなツールが作成されています。この付録では、この仕様に準拠するユースケースとアクションについて説明します。
一緒に使用することを目的としたスキーマリソースのセットは、それぞれ独自のスキーマドキュメントに、すべて同じスキーマドキュメントに、またはその間の任意の粒度のドキュメントグループで編成できます。
さまざまな種類の参照削除を実行するためのツールが多数存在します。これの一般的なケースは、すべての参照がそのファイル内で解決できる単一のファイルを生成することです。これは通常、配布を簡素化するため、またはJSONスキーマライブラリのさまざまな呼び出しが多数のリソースを追跡してロードする必要がないようにコーディングを簡素化するために行われます。
この変換は、すべての静的参照 (例: "$ref") が正規URIに解決されるURI参照を使用し、すべてのスキーマリソースがルートスキーマに "$id" として絶対URIを持っている限り、安全かつ可逆的に実行できます。
これらの条件が満たされていれば、外部リソースはそれぞれ "$defs" の下にコピーでき、リソースのスキーマオブジェクト間の参照を壊すことなく、検証または注釈の結果の側面を変更することはありません。 "$defs" 下のスキーマの名前は、埋め込まれたリソースの正規URIに表示されないため、それぞれが一意であると仮定すると、動作には影響しません。
すべての参照を削除して単一のスキーマドキュメントを生成しようとすると、すべての場合において、元の形式と同一の動作をするスキーマが生成されるとは限りません。
"$ref" は他のキーワードと同様に扱われるようになり、同じスキーマオブジェクトで他のキーワードを使用できるため、すべての場合で非再帰的な "$ref" 削除を完全にサポートするには、比較的複雑なスキーマ操作が必要になる場合があります。安全な "$ref" 削除変換のセットを決定または提供することは、この仕様の範囲外です。これらはスキーマ構造だけでなく、意図された使用法にも依存するためです。
単純な再帰的ツリー構造を記述する次の2つのスキーマを検討してください。ツリー内の各ノードは、任意のタイプの "data" フィールドを持つことができます。最初のスキーマでは、他のインスタンスプロパティを許可して無視します。2番目のスキーマはより厳密で、"data" および "children" プロパティのみを許可します。"data" が "daat" と綴られているインスタンスの例も示します。
// tree schema, extensible { "$schema": "https://json-schema.dokyumento.jp/draft/2019-09/schema", "$id": "https://example.com/tree", "$recursiveAnchor": true, "type": "object", "properties": { "data": true, "children": { "type": "array", "items": { "$recursiveRef": "#" } } } } // strict-tree schema, guards against misspelled properties { "$schema": "https://json-schema.dokyumento.jp/draft/2019-09/schema", "$id": "https://example.com/strict-tree", "$recursiveAnchor": true, "$ref": "tree", "unevaluatedProperties": false } // instance with misspelled field { "children": [ { "daat": 1 } ] }
インスタンスに "strict-tree" スキーマを適用すると、"$ref" から "tree" スキーマに移動し、その "children" サブスキーマを調べ、その "items" サブスキーマに "$recursiveAnchor" を見つけます。この時点で、動的パスは "#/$ref/properties/children/items/$recursiveRef" です。
この時点でのベースURIは "https://example.com/tree" であるため、"$recursiveRef" は最初に "https://example.com/tree#" に解決されます。"$recursiveAnchor" が true であるため、異なるベースURIを使用するかどうかを確認するために動的パスを調べます。 "#" と "#/$ref" の動的パスで true 値の "$recursiveAnchor" を見つけます。
最も外側は "#" であり、これは "strict-tree" スキーマのルートスキーマであるため、そのベースURI "https://example.com/strict-tree" を使用します。これにより、"$recursiveRef" の最終的な解決済みURI "https://example.com/strict-tree#" が生成されます。
このようにして、"tree" スキーマの再帰は、インスタンスルートにのみ "strict-tree" を適用するのではなく、"strict-tree" のルートに再帰し、インスタンスの子に "tree" を適用します。
語彙の作成者は、語彙が幅広い用途を目的としており、他の語彙と組み合わされる可能性がある場合に、キーワード名の衝突を回避するように注意する必要があります。JSONスキーマは、正式な名前空間システムを提供しませんが、キーワード名を制約せず、任意の数の名前空間アプローチを可能にします。
語彙は、別の語彙からのキーワードの動作に関してキーワードの動作を定義したり、別の語彙からのキーワードを許容される値の制限されたまたは拡張されたセットで使用したりするなど、互いに構築することができます。このようなすべての語彙の再利用が、構築された語彙と互換性のある新しい語彙になるわけではありません。語彙の作成者は、期待される互換性のレベル(もしあれば)を明確に文書化する必要があります。
メタスキーマの作成者は、同じキーワードに対して矛盾する構文またはセマンティクスを定義する複数の語彙を組み合わせるために "$vocabulary" を使用しないでください。セマンティックの競合は通常、スキーマ検証では検出できないため、実装でそのような競合を検出することは期待されていません。矛盾する語彙が宣言された場合、結果の動作は未定義です。
語彙の作成者は、語彙のキーワードの期待される使用法を独自に検証するメタスキーマを提供する必要があります。このようなメタスキーマは、追加のキーワードを禁止してはならず、コア語彙のキーワードを禁止してはなりません。
メタスキーマの作成者は、"allOf"キーワードを使用して、各語彙のメタスキーマを参照することをお勧めしますが、メタスキーマを構築するための他のメカニズムが特定のユースケースに適している場合があります。
メタスキーマの再帰的な性質により、既存のメタスキーマを拡張するために "$recursiveAnchor" および "$recursiveRef" キーワードが特に役立ちます。これは、検証メタスキーマを拡張するJSONハイパースキーマメタスキーマで見ることができます。
メタスキーマは、宣言された語彙に関連付けられたメタスキーマが記述するものを超えて、語彙に存在しないキーワードを記述することを含め、追加の制約を課す場合があります。これにより、使用法を語彙のサブセットに制限したり、再利用を目的としないローカルで定義されたキーワードを検証したりできます。
ただし、メタスキーマは、語彙が期待するJSONタイプとは異なるタイプを要求するなど、宣言する語彙と矛盾してはなりません。結果の動作は未定義です。
任意の実装での語彙のサポートをテストする必要がなく、ローカルで使用することを目的としたメタスキーマは、"$vocabulary" を完全に省略しても安全です。
このメタスキーマは、コア語彙とアプライケータ語彙の両方を、拡張語彙とともに明示的に宣言し、それらのメタスキーマを "allOf" で結合します。拡張語彙のメタスキーマ(その語彙のキーワードのみを記述します)は、メインのメタスキーマ例の後に示されます。
主なメタスキーマは、特に実装が複雑な「unevaluated」プレフィックスの付いたキーワードの使用を禁止することで、Applicatorボキャブラリーの使用も制限しています。これは、Applicatorボキャブラリーによって定義されたセマンティクスやキーワードのセットを変更するものではありません。これは、このメタスキーマを使用するスキーマが、「unevaluted」プレフィックスの付いたキーワードを使用しようとすると、このメタスキーマに対する検証に失敗することを保証するだけです。
最後に、このメタスキーマは、どのボキャブラリーにも属さないキーワード「localKeyword」の構文を記述します。おそらく、このメタスキーマの実装者とユーザーは、「localKeyword」のセマンティクスを理解するでしょう。JSON Schemaは、ボキャブラリー外でキーワードのセマンティクスを表現するメカニズムを定義していないため、理解されている特定の環境以外での使用には適していません。
このメタスキーマは、一般的な使用のためにいくつかのボキャブラリーを組み合わせています。
{ "$schema": "https://json-schema.dokyumento.jp/draft/2019-09/schema", "$id": "https://example.com/meta/general-use-example", "$recursiveAnchor": true, "$vocabulary": { "https://json-schema.dokyumento.jp/draft/2019-09/vocab/core": true, "https://json-schema.dokyumento.jp/draft/2019-09/vocab/applicator": true, "https://json-schema.dokyumento.jp/draft/2019-09/vocab/validation": true, "https://example.com/vocab/example-vocab": true }, "allOf": [ {"$ref": "https://json-schema.dokyumento.jp/draft/2019-09/meta/core"}, {"$ref": "https://json-schema.dokyumento.jp/draft/2019-09/meta/applicator"}, {"$ref": "https://json-schema.dokyumento.jp/draft/2019-09/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/2019-09/schema", "$id": "https://example.com/meta/example-vocab", "$recursiveAnchor": true, "$vocabulary": { "https://example.com/vocab/example-vocab": true, }, "type": ["object", "boolean"], "properties": { "minDate": { "type": "string", "pattern": "\d\d\d\d-\d\d-\d\d", "format": "date", } } }
上記のように、汎用メタスキーマの「allOf」で参照されている単一ボキャブラリーのメタスキーマのそれぞれが、対応するボキャブラリーを宣言している場合でも、この新しいメタスキーマはそれらを再宣言する必要があります。
CoreおよびValidation仕様で定義されたすべてのボキャブラリーを組み合わせた標準メタスキーマ、およびこれらの仕様とHyper-Schema仕様で定義されたすべてのボキャブラリーを組み合わせた標準メタスキーマは、追加の複雑な組み合わせを示しています。これらのメタスキーマのURIは、それぞれValidation仕様およびHyper-Schema仕様に記載されています。
汎用メタスキーマは「minDate」の構文を検証できますが、「minDate」のセマンティックな意味の背後にあるロジックを定義するのはボキャブラリーです。セマンティクス(この例では、インスタンス値が、スキーマ内のキーワードの値として提供された日付以降の日付である必要があるということ)を理解していなければ、実装は構文的な使用法しか検証できません。この場合、それは日付形式の文字列であることを検証することを意味します(「format」が純粋にアノテーションとして機能する場合でも検証されることを保証するために、「pattern」を使用して、「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氏、Ben Hutton氏、Evgeny Poberezkin氏、Brad Bowman氏、Gowry Sankar氏、Donald Pipowitch氏、Dave Finlay氏に感謝いたします。
[CREF15]このセクションは、インターネットドラフトのステータスを離れる前に削除されます。