インターネットエンジニアリングタスクフォース | A. ライト 編 |
インターネットドラフト | |
意図されたステータス:参考情報 | H. アンドリュース 編 |
期限切れ:2017年10月23日 | Cloudflare, Inc. |
2017年4月21日 |
JSON スキーマ:JSON ドキュメントを記述するためのメディアタイプ
draft-wright-json-schema-01
JSON スキーマは、JSON データの構造を記述するためのJSON ベースのフォーマットであるメディアタイプ "application/schema+json" を定義します。JSON スキーマは、JSON ドキュメントがどのようなものであるべきか、そこから情報を抽出する方法、そしてそれとの対話方法を表明します。これは、それ以外の方法ではハイパーメディア制御を持たない、または機械可読でない既存のJSON API に注釈を付けるのに理想的です。
このドラフトの課題一覧は、<https://github.com/json-schema-org/json-schema-spec/issues> で確認できます。
詳細については、<https://json-schema.dokyumento.jp/> を参照してください。
フィードバックを提供するには、この課題トラッカー、ホームページに記載されている連絡方法、またはドキュメント編集者への電子メールを使用してください。
このインターネットドラフトは、BCP 78およびBCP 79の規定に完全に準拠して提出されています。
インターネットドラフトは、インターネットエンジニアリングタスクフォース(IETF)の作業文書です。他のグループもインターネットドラフトとして作業文書を配布することに注意してください。現在のインターネットドラフトのリストは、http://datatracker.ietf.org/drafts/current/にあります。
インターネットドラフトは最大6ヶ月間有効なドラフト文書であり、いつでも他の文書によって更新、置換、または廃止される可能性があります。「進行中の作業」以外に、インターネットドラフトを参照資料として使用したり、引用したりすることは適切ではありません。
このインターネットドラフトは、2017年10月23日に期限切れになります。
Copyright (c) 2017 IETF Trustおよび文書の著者として特定された人物。全著作権所有。
この文書は、BCP 78およびIETF文書に関するIETFトラストの法的規定(http://trustee.ietf.org/license-info)(この文書の公開日に有効)の対象となります。これらの文書をよく確認してください。これらには、この文書に関するあなたの権利と制限が記述されています。この文書から抽出されたコードコンポーネントには、トラストの法的規定のセクション4.eに記載されているように、簡略化されたBSDライセンステキストを含める必要があり、簡略化されたBSDライセンスに記載されているように、保証なしで提供されます。
JSON スキーマは、JSON データの構造を定義するための JSON メディアタイプです。JSON スキーマは、JSON データの検証、ドキュメント化、ハイパーリンク ナビゲーション、およびインタラクション制御を定義することを目的としています。
この仕様では、JSON スキーマのコア用語とメカニズムを定義しています。これには、参照による別の JSON スキーマへのポインティング、JSON スキーマ参照の逆参照、および使用されている語彙の指定が含まれます。
他の仕様では、検証、リンク、アノテーション、ナビゲーション、およびインタラクションに関するアサーションを実行する語彙を定義しています。
この文書におけるキーワード「MUST」、「MUST NOT」、「REQUIRED」、「SHALL」、「SHALL NOT」、「SHOULD」、「SHOULD NOT」、「RECOMMENDED」、「MAY」、「OPTIONAL」は、RFC 2119 [RFC2119]で説明されているように解釈されます。
この文書における用語「JSON」、「JSON テキスト」、「JSON 値」、「メンバ」、「要素」、「オブジェクト」、「配列」、「数値」、「文字列」、「ブール値」、「true」、「false」、「null」は、RFC 7159 [RFC7159]で定義されているように解釈されます。
この文書では、JSON データを記述するための JSON スキーマを識別するための新しいメディアタイプ "application/schema+json" を提案します。JSON スキーマ自体は JSON ドキュメントです。これと関連する仕様では、作成者がいくつかの方法で JSON データを記述できるキーワードを定義しています。
JSON スキーマは、JSON ドキュメントの構造(たとえば、必須のプロパティと長さの制限)を記述します。アプリケーションは、この情報を使用してインスタンスを検証したり(制約が満たされていることを確認したり)、制約が満たされるようにユーザー入力の収集を行うインターフェースを通知したりできます。
検証の動作とキーワードは、別のドキュメント [json-schema-validation]で指定されています。
JSON ハイパー スキーマは、JSON ドキュメントのハイパーテキスト構造を記述します。これには、インスタンスから他のリソースへのリンク関係、インスタンスのマルチメディアデータとしての解釈、およびAPI の使用に必要な送信データが含まれます。
ハイパー スキーマの動作とキーワードは、別のドキュメント [json-hyper-schema]で指定されています。
JSON ドキュメントは、application/json メディアタイプで記述された情報リソース(一連のオクテット)です。
JSON スキーマでは、データモデルを定義しているため、「JSON ドキュメント」、「JSON テキスト」、「JSON 値」という用語は互換性があります。
JSON スキーマは、JSON ドキュメントに対してのみ定義されます。ただし、JSON スキーマ データモデルに従って解析または処理できるドキュメントやメモリ構造は、CBOR [RFC7049]のようなメディアタイプを含む、JSON スキーマに対して解釈できます。
JSON スキーマは、データモデルに従ってドキュメントを解釈します。このデータモデルに従って解釈された JSON 値を「インスタンス」と呼びます。
インスタンスは、6 つのプリミティブ型のいずれかの型を持ち、型に応じてさまざまな値が可能です。
空白とフォーマットに関する懸念事項は、JSON スキーマの範囲外です。
オブジェクトは同じキーを持つ2つのプロパティを持つことができないため、単一オブジェクト内で同じキー("string" 生成)を持つ2つのプロパティ("member" 生成)を定義しようとするJSONドキュメントの動作は定義されていません。
2つのJSONインスタンスは、データモデルに従って同じ型であり、同じ値を持つ場合に限り、等しいと言われます。具体的には、これは次のことを意味します。
この定義では、配列の長さは同じでなければならないこと、オブジェクトは同じ数のメンバーを持たなければならないこと、オブジェクト内のプロパティは順序付けられていないこと、同じキーを持つ複数のプロパティを定義する方法がないこと、そして単なるフォーマットの違い(インデント、コンマの位置、末尾のゼロ)は重要ではないことが暗黙的に示されています。
JSON スキーマ文書、または単にスキーマとは、インスタンスを記述するために使用される JSON ドキュメントです。スキーマはそれ自体がインスタンスとして解釈されます。JSON スキーマは、オブジェクトまたはブール値でなければなりません。
ブール値は、次の動作に相当します。
インスタンスを記述するために使用されるプロパティをキーワードまたはスキーマキーワードと呼びます。プロパティの意味は、スキーマが使用している語彙によって指定されます。
JSON スキーマには、スキーマキーワードではないプロパティを含めることができます。不明なキーワードは無視する必要があります。
それ自体がスキーマを記述するスキーマをメタスキーマと呼びます。メタスキーマは、JSON スキーマを検証し、使用している語彙を指定するために使用されます。
空のスキーマとは、プロパティがないか、または不明なプロパティのみを持つ JSON スキーマです。
ルートスキーマは、問題の JSON ドキュメント全体を構成するスキーマです。
一部のキーワードはそれ自体がスキーマを使用するため、JSON スキーマはネストできます。
{ "title": "root", "items": { "title": "array item" } }
この例文書では、「配列項目」というタイトルのスキーマはサブスキーマであり、「ルート」というタイトルのスキーマはルートスキーマです。
ルートスキーマと同様に、サブスキーマはオブジェクトまたはブール値のいずれかです。
[RFC6839]のセクション3.1に従って、任意の+jsonメディアタイプに対して指定されたフラグメント識別子の構文とセマンティクスは、「application/json」に対して指定されたものと同じである必要があります。(この文書の公開時点では、「application/json」に対して定義されたフラグメント識別構文はありません。)
さらに、「application/schema+json」メディアタイプは、プレーン名とJSONポインタの2つのフラグメント識別子構造をサポートしています。URIフラグメント識別子としてのJSONポインタの使用については、RFC 6901 [RFC6901]で説明されています。空文字列を含むJSONポインタ構文に一致するフラグメント識別子は、JSONポインタフラグメント識別子として解釈する必要があります。
W3Cのフラグメント識別子のベストプラクティス [W3C.WD-fragid-best-practices-20121025]に従って、プレーン名のフラグメント識別子は、ローカルに名前付けされたスキーマを参照するために予約されています。JSONポインタ構文と一致しないすべてのフラグメント識別子は、プレーン名のフラグメント識別子として解釈する必要があります。
"$id"キーワード [id-keyword]セクションで、プレーン名のフラグメント識別子の定義と参照を説明します。
インスタンスは、JSON [RFC7159]で定義されている任意の有効な JSON 値にすることができます。JSON スキーマは型に制限を課しません。JSON スキーマは、null など、任意の JSON 値を記述できます。
JSON スキーマはプログラミング言語に依存せず、データモデルで記述されているあらゆる値をサポートします。ただし、一部の言語や JSON パーサーでは、JSON で記述可能なすべての値をメモリ上に表現できない場合があります。
一部のプログラミング言語とパーサーでは、浮動小数点数と整数の内部表現が異なります。
整合性を保つため、整数型の JSON 数値には小数部分をエンコードすべきではありません。
実装では、JSON スキーマに追加のキーワードを定義しても構いません。明示的な合意がない限り、スキーマ作成者は、これらの追加キーワードがピア実装でサポートされるとは期待すべきではありません。実装は、サポートしていないキーワードを無視するべきです。
JSON スキーマの拡張を作成する場合は、"allOf" を使用して既存のメタスキーマを拡張する独自のメタスキーマを作成することをお勧めします。この拡張メタスキーマは "$schema" キーワードを使用して参照するべきであり、ツールが正しい動作に従うことができます。
"$schema" キーワードは、JSON スキーマのバージョン識別子と、この特定のバージョンで記述されたスキーマを記述する JSON スキーマ自体であるリソースの場所の両方として使用されます。
このキーワードの値は、URI [RFC3986](スキームを含む)でなければならず、この URI は正規化されている必要があります。現在のスキーマはこの URI によって識別されるメタスキーマに対して有効である必要があります。
"$schema" キーワードはルートスキーマで使用されるべきです。サブスキーマには表示されるべきではありません。
[CREF1]このパターンはスキーマ作成のベストプラクティスとして残る可能性が高いですが、実装の動作は将来のドラフトで改訂または緩和される可能性があります。
このプロパティの値は、他のドキュメントや他の当事者によって定義されています。JSON スキーマの実装では、妥当と思われるJSON スキーマ用語集の現在および以前の公開ドラフトのサポートを実装する必要があります。
"$ref" キーワードはスキーマを参照するために使用され、自己参照を通じて再帰構造を検証する機能を提供します。
"$ref" プロパティを持つオブジェクトスキーマは、"$ref" 参照として解釈する必要があります。"$ref" プロパティの値は URI 参照である必要があります。現在の URI ベースに対して解決され、使用するスキーマの URI を識別します。"ref" オブジェクト内の他のすべてのプロパティは無視する必要があります。
URI はネットワークロケーターではなく、識別子です。スキーマは、ネットワークアドレス可能な URL である場合でも、アドレスからダウンロードする必要はなく、実装はネットワークアドレス可能な URI を検出したときにネットワーク操作を実行すると想定するべきではありません。
スキーマに対して無限ループに陥るスキーマがあってはなりません。たとえば、2 つのスキーマ "#alice" と "#bob" が両方とも、もう一方を参照する "allOf" プロパティを持っている場合、単純なバリデーターはインスタンスの検証を試みる際に無限の再帰ループに陥る可能性があります。スキーマは、このような無限の再帰的ネストを使用するべきではありません。その動作は未定義です。
RFC3986 セクション 5.1 [RFC3986] は、ドキュメントのデフォルトのベース URI を決定する方法を定義しています。
参考情報として、スキーマの初期ベース URI は、スキーマが見つかった URI、または不明な場合は適切な代替 URI です。
"$id" キーワードはスキーマの URI と、スキーマ内の他の URI 参照が解決されるベース URI を定義します。"id" キーワード自体は、オブジェクト全体が表示されるベース URI に対して解決されます。
存在する場合、このキーワードの値は文字列でなければならず、有効なURI 参照 [RFC3986] を表す必要があります。この値は正規化されるべきであり、空のフラグメント <><#> または空の文字列 <><> であってはなりません。
JSON スキーマドキュメントのルートスキーマには、URI(スキームを含む)を持つ "$id" キーワードが含まれている必要があります。このURIは、フラグメントを持たないか、空の文字列である必要があります。[CREF2]他のコンポーネントを含むフラグメントを含む "$id" URI 参照はどのように解釈されるべきでしょうか?他のコンポーネントが現在のベース URI と一致する場合と、ベース URI を変更する場合の 2 つのケースがあります。
JSON スキーマドキュメントでサブスキーマに名前を付けるために、サブスキーマは "$id" を使用してドキュメントローカルの識別子を自身に与えることができます。これは、"$id" をフラグメントのみからなる URI 参照に設定することで行われます。フラグメント識別子は、文字 ([A-Za-z]) で始まり、任意の数の文字、数字 ([0-9])、ハイフン ("-")、アンダースコア ("_")、コロン (":")、またはピリオド (".") が続きます。
上記の要件にも合致せず、有効な JSON ポインターでもない "$id" を定義した場合の影響は定義されていません。
{ "$id": "http://example.com/root.json", "definitions": { "A": { "$id": "#foo" }, "B": { "$id": "other.json", "definitions": { "X": { "$id": "#bar" }, "Y": { "$id": "t/inner.json" } } }, "C": { "$id": "urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f" } } }
例
以下の URI エンコードされたJSON ポインター [RFC6901](ルートスキーマを基準とする)にあるスキーマは、上記のセクション5に従って、次のベース URI を持ち、いずれかの URI で識別可能です。
スキーマは、JSON ポインター、または "$id" によって直接与えられた URI を含め、与えられた URI で識別できます。
ツールは、サブスキーマを含むスキーマが "$id" を使用して自身に提供する URI に注意する必要があります。これは「内部参照」と呼ばれます。
たとえば、次のスキーマを考えてみましょう。
{ "$id": "http://example.net/root.json", "items": { "type": "array", "items": { "$ref": "#item" } }, "definitions": { "single": { "$id": "#item", "type": "integer" } } }
実装が <><#/definitions/single> スキーマを検出すると、現在のベース URI に対して "$id" URI 参照を解決して <><http://example.net/root.json#item> を形成します。
次に、実装が <><#/items> スキーマ内を見ると、 <><#item> 参照を検出し、これを <><http://example.net/root.json#item> に解決します。これは、同じドキュメントの他の場所で定義されているスキーマとして理解されます。
広範なエコシステムにおいてスキーマを互いに区別するために、スキーマは URI で識別されます。上記で指定されているように、これは必ずしも何かがダウンロードされることを意味するわけではなく、JSON スキーマの実装は、それらを識別する URI を含め、使用するスキーマを既に理解している必要があります。
実装は、バリデーターがスキーマをどの程度信頼しているかによって、任意の URI を任意のスキーマに関連付けるか、スキーマの "$id" で与えられた URI を自動的に関連付けることができる必要があります。
スキーマは複数の URI を持つことができます(そして、おそらく持つでしょう)が、1 つの URI が複数のスキーマを識別することはできません。複数のスキーマが同じ URI で識別しようとすると、バリデーターはエラー状態を発生させる必要があります。
JSON は、自動化された API とロボットのために HTTP サーバーで広く採用されています。このセクションでは、メディアタイプとWeb リンク [RFC5988]をサポートするプロトコルで使用する場合に、JSON ドキュメントの処理をより RESTful な方法で強化する方法について説明します。
スキーマ/プロファイルで記述されているインスタンスは、Linked Data Protocol 1.0、セクション 8.1 [W3C.REC-ldp-20150226]で定義されているように、「describedby」というリンクリレーションを使用して、ダウンロード可能な JSON スキーマへのリンクを提供することをお勧めします。
HTTP では、このようなリンクはLink ヘッダー [RFC5988]を使用して任意のレスポンスに添付できます。そのようなヘッダーの例は次のとおりです。
Link: <http://example.com/my-hyper-schema#>; rel="describedby"
インスタンスは、'profile' リンクリレーション [RFC6906]で説明されているように「profile」を指定しても構いません。メディアタイプパラメーターとして使用する場合、HTTP サーバーはプロファイルに基づいてコンテンツタイプネゴシエーションを実行できるようになります。メディアタイプパラメーターは、スペースで区切られた URI のリストである必要があります(つまり、相対参照は無効です)。
プロファイル URI は不透明であり、自動的に逆参照されるべきではありません。実装が提供されたプロファイルのセマンティクスを理解していない場合、実装は代わりに(存在する場合)「describedby」リンクに従うことができます。これはプロファイルの処理方法に関する情報を提供する可能性があります。「profile」は必ずしもネットワークの場所を指すわけではないため、「describedby」リレーションはダウンロード可能なスキーマへのリンクに使用されます。ただし、簡潔にするため、スキーマ作成者は可能な限りこれらの URI を同じリソースにポイントする必要があります。
HTTP では、メディアタイプパラメーターは Content-Type ヘッダー内に送信されます。
Content-Type: application/json; profile="http://example.com/my-hyper-schema#"
複数のプロファイルはスペースで区切られます。
Content-Type: application/json; profile="http://example.com/alice http://example.com/bob"
HTTP は Link でも「profile」を送信できますが、これにより、メディアタイプパラメーターを完全に置き換える場合、メディアタイプのセマンティクスとコンテンツタイプのネゴシエーションに影響を与える可能性があります。
Link: </alice>;rel="profile", </bob>;rel="profile"
ネットワーク上のハイパーメディアシステムで使用する場合、HTTP [RFC7231] はスキーマを配布するためのプロトコルの選択肢として頻繁に使用されます。動作の悪いクライアントは、代わりにスキーマを長時間キャッシュすることが可能な場合に、ネットワーク経由でスキーマを必要以上に頻繁に取得すると、サーバー管理者に問題を引き起こす可能性があります。
HTTP サーバーは、JSON スキーマに長期間有効なキャッシュヘッダーを設定する必要があります。HTTP クライアントは、キャッシュヘッダーを遵守し、有効期限内にドキュメントを再要求するべきではありません。分散システムは、共有キャッシュやキャッシングプロキシを使用する必要があります。
User-Agent: product-name/5.4.1 so-cool-json-schema/1.0.2 curl/7.43.0
クライアントは、JSON スキーマの実装またはソフトウェア製品に固有の User-Agent ヘッダーを設定または追加する必要があります。記号は重要度の低い順にリストされているため、JSON スキーマライブラリの名前/バージョンは、より一般的な HTTP ライブラリの名前(存在する場合)の前に付ける必要があります。たとえば
クライアントは、「From」ヘッダーを使用して要求を行うことができるようにする必要があります。これにより、サーバーオペレーターは、動作の悪いスクリプトの所有者に連絡できます。
スキーマとインスタンスの両方とも JSON 値です。そのため、RFC 7159 [RFC7159]で定義されているすべてのセキュリティに関する考慮事項が適用されます。
インスタンスとスキーマはどちらも、パブリックインターネットサーバーに展開されるために、信頼されていないサードパーティによって頻繁に記述されます。バリデーターは、スキーマの解析が過剰なシステムリソースを消費しないように注意する必要があります。バリデーターは無限ループに陥るべきではありません。
サーバーは、悪意のある当事者が、既存のスキーマの機能を、既存のまたは非常に類似した "$id" を持つスキーマをアップロードすることによって変更できないように注意する必要があります。
個々のJSONスキーマ語彙には、独自のセキュリティに関する考慮事項がある可能性があります。詳細については、それぞれの仕様を参照してください。
JSONスキーマで提案されているMIMEメディアタイプは以下のとおり定義されます。
[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、「Additional Media Type Structured Syntax Suffixes」、RFC 6839、DOI 10.17487/RFC6839、2013年1月。 |
[RFC6901] | Bryan, P.、Zyp, K.およびM. Nottingham、「JavaScript Object Notation (JSON) Pointer」、RFC 6901、DOI 10.17487/RFC6901、2013年4月。 |
[RFC7159] | Bray, T.、「The JavaScript Object Notation (JSON) Data Interchange Format」、RFC 7159、DOI 10.17487/RFC7159、2014年3月。 |
[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月。 |
[RFC5988] | Nottingham, M.、「Web Linking」、RFC 5988、DOI 10.17487/RFC5988、2010年10月。 |
[RFC6906] | Wilde, E.、「The 'profile' Link Relation Type」、RFC 6906、DOI 10.17487/RFC6906、2013年3月。 |
[RFC7049] | Bormann, C.およびP. Hoffman、「Concise Binary Object Representation (CBOR)」、RFC 7049、DOI 10.17487/RFC7049、2013年10月。 |
[RFC7231] | Fielding, R.およびJ. Reschke、「Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content」、RFC 7231、DOI 10.17487/RFC7231、2014年6月。 |
[W3C.WD-fragid-best-practices-20121025] | Tennison, J.、「Best Practices for Fragment Identifiers and Media Type Definitions」、World Wide Web Consortium LastCall WD-fragid-best-practices-20121025、2012年10月。 |
[json-schema-validation] | Wright, A.およびG. Luff、「JSON Schema Validation: A Vocabulary for Structural Validation of JSON」、Internet-Draft draft-wright-json-schema-validation-00、2016年10月。 |
[json-hyper-schema] | Wright, A.およびG. Luff、「JSON Hyper-Schema: A Vocabulary for Hypermedia Annotation of JSON」、Internet-Draft draft-wright-json-schema-hyperschema-00、2016年10月。 |
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の皆様に感謝いたします。
[CREF3]インターネットドラフトのステータスを離れる前に、このセクションは削除されます。