2022年1月21日(金) ·9分の読書

JSON Schemaを5分で理解する

今までJSON Schemaについて聞いたことがないなら、詳しく学ぶには最適な場所です。JSON Schemaの利用に自信がある方でも、この記事にはまだ価値があり、何か新しいことを学べる可能性があります。

この記事を読み終えるころには、あなたは

  • JSON Schemaとは何かを理解している
  • JSON Schemaで何ができるかを知っている
  • JSON Schemaについて話すための重要な用語を理解している
  • JSON Schemaの基本的な仕組みをいくつか知っている
  • JSON Schemaの経験が数年ある人よりも優れている(願わくば)

これは技術的な入門ですが、今日はコードを書くことはありません。しかし、ほとんどすべてのプログラミング言語での実装リストへのリンクを提供します。

JSONとは?

主に、JSON Schemaはデータを検証するために使用されます。JSON Schemaが検証できるデータの種類は、JSONでエンコードされたデータです。

JSONはJavaScript Object Notationの略で、JavaScriptのサブセットです。JSONは人間と機械の両方が読み取り可能であるため、データ交換のための一般的な形式の選択肢です。

JSON Schemaは、プロジェクトと必要な検証を定義する成果物(JSON Schema)の両方に与えられた名前です。検証ルールは、JSONデータに対する制約を定義することによって表現されます。

検証対象のJSONデータは「JSONインスタンス」と呼ばれます。

JSON Schema

JSON Schemaプロジェクトは、組織名「json-schema-org」の下でGitHubにあります。これは、仕様とサポートリソースに対する変更を追跡し、コラボレーションを可能にするために使用されるいくつかのgitリポジトリで構成されています。

JSON Schema仕様は、現在、Internet Engineering Task Force(IETF)を通じて一連の「個人ドラフト」として標準的に公開されている技術仕様ドキュメントで構成されています。「個人ドラフト」とは、IETFの作業グループからのIETFで公開されたドキュメントに与えられたカテゴリです。

JSON Schemaドキュメントは、JSON自体で記述されます。JSONで記述されているということは、ほぼすべてのプログラミング言語で読み取ることができるため、相互運用可能な検証ソリューションになります。JSONに変換される他の形式を使用したり、JSONにシリアル化できるコードを使用して記述することもできます。

JSON Schema(ドキュメント)

JSON Schema自体がJSONであることを述べました。以前は、JSONはルートレベルでオブジェクトまたは配列である必要がありましたが、今日では、許可された値のいずれかである可能性もあります。

JSON Schemaは、オブジェクトまたはブール値である可能性があります。ブール形式は、検証アサーションの結果と同じ値になります。オブジェクト形式では、キーワードと値を使用して検証の制約を表現できます。

JSON Schemaは制約ベースであるため、定義(または制約)されていないものはすべて許可され、有効と見なされます。

スキーマにブール値を許可するのは奇妙に思えるかもしれませんが、それがなぜ後で役立つのかを検討します。今のところ、最初のスキーマの例を見てみましょう。

制約の紹介

データ
{}
空のオブジェクト
データ
true
"true"のブール値
データ
false
"false"のブール値
データ
{ "not": { } }
Not、空のオブジェクト

スキーマを順番に取り上げて、検証結果を説明しましょう。

空のオブジェクトスキーマは制約を表現しません。インスタンスデータは常に有効と見なされます。「true」のブール値スキーマは、インスタンスデータが有効であることを常にアサートします。

ご想像のとおり、残りの2つのスキーマでは逆が当てはまります。「false」のブール値スキーマは常にfalseをアサートし、「Not、空のオブジェクト」スキーマは同じ結果になります。

notキーワードは、その値としてJSON Schemaを取ります。これらの「スキーマ値」はサブスキーマと呼ばれます。サブスキーマはインスタンスデータに適用され、結果のアサーションが反転されます。すでに述べたように、空のオブジェクトスキーマは「true」のアサーションになるため、逆は「false」になります。

オブジェクトスキーマ

オブジェクトスキーマのキーは、JSON Schemaキーワードです。これらのキーワードには、識別子、アプリケータ、アサーション、およびアノテーションの4つのクラスがあります。一部のキーワードは、独自の機能があるため、これらのクラスには適合しません。

$schemaキーワードには独自の機能があります。このキーワードの値は、スキーマの処理時に使用するJSON Schema方言を識別するURIです。

JSON Schema方言は、定義された意味を持つキーワードのセットと考えることができます。ほとんどの場合、扱うさまざまな方言は、JSON Schemaの単に異なるバージョン(または「ドラフト」)です。

$schemaキーワードを使用して、使用中のJSON Schema方言を定義することをお勧めします。そうすることで、実装はサポートしていないJSON Schemaのバージョンを見つけた場合、エラーをスローする必要があります。

スキーマが使用しているJSON Schemaの方言を定義していない場合、実装は任意の方言を選択する可能性があります。これにより、そのバージョンをサポートしていない実装で使用した場合に、誤検出が発生する可能性があります。

この入門では、JSON Schemaの2020-12バージョンを使用しますが、ここで学ぶことのほとんどは、今日本番環境で使用されているほぼすべてのバージョンに適用されます。

2020-12 JSON Schema方言のURIは、https://json-schema.dokyumento.jp/draft/2020-12/schemaです。

アサーション

JSON Schemaが制約ベースの検証を提供することを覚えておいてください。JSON Schemaは、インスタンスに適用された場合にアサーション結果(合格または不合格)を提供するキーワードを定義します。

"const"キーワード

最も単純なアサーションキーワードはconstです。値は有効なJSONにすることができます。検証に合格するには、データがconstの値と同じである必要があります。例を次に示します

スキーマ
{ "const": 1234 }
データ
1234
スキーマに準拠
有効 - まったく同じです
データ
"foobar"
スキーマに準拠していません
無効 - 同じではありません

"type"キーワード

別のアサーションキーワードはtypeです。その値は、許可された型である文字列の配列です。型は、JSONによって定義された6つのプリミティブ型と、「整数」です。例を見てみましょう。

スキーマ
{ "type": ["object", "boolean", "null"] }
データ
{ "ok": "yes" }
スキーマに準拠
有効 - オブジェクトは許可されています。
データ
true
スキーマに準拠
有効 - ブール値は許可されています。
データ
null
スキーマに準拠
有効 - Nullは許可されています。
データ
123
スキーマに準拠していません
無効 - 数値は許可されていません。
データ
"foobar"
スキーマに準拠していません
無効 - 文字列は許可されていません。

これら2つのアサーションキーワードは、JSON内の任意の種類のデータに適用できますが、一部のアサーションキーワードは特定のタイプにのみ適用可能です。キーワードがインスタンスデータに適用できない場合、それは無視され、検証は実行されません。

「required」キーワード

requiredは、オブジェクトにのみ適用可能なアサーションキーワードです。いくつかの例を使って、これの意味を探ってみましょう。

{ "required": ["name"] } - 私たちのJSONスキーマ { "name": "Bob" } - 有効 - 「name」はオブジェクト内にあります。{ "fullName": "Bob" } - 無効 - 「name」がオブジェクトから欠落しています。"Bob" - 有効 - requiredキーワードはオブジェクトにのみ適用されます。true - 有効 - 上記と同じです。

これは驚くかもしれませんが、特定の種類のデータが与えられた場合にのみ論理的に意味のある制約の構成を可能にします。

タイプの期待の不一致を避けるために、同じスキーマ内でtypeを他のキーワードと組み合わせて使用する必要があります。

アプリケーター

検証は、ルートスキーマを完全なインスタンスドキュメントに適用することから始まります。アプリケーターキーワードは、インスタンスの場所に対してサブスキーマを適用します。

「properties」キーワード

最も一般的に使用されるアプリケーターキーワードはpropertiesで、これはオブジェクト値を持ち、値はサブスキーマです。実際に動作を見てみましょう。

スキーマ
{ "properties": { "name": { "type": ["string"] } }}
私たちのJSONスキーマ
データ
{ "name": "Alice"}
スキーマに準拠
インスタンスにはnameがあり、それは文字列です
データ
{ "fullName": "Alice"}
スキーマに準拠
インスタンスオブジェクトには `name` プロパティがありません。
データ
[ "name", 123 ]
スキーマに準拠
インスタンスはオブジェクトではないため、`properties` は適用されません。

サブスキーマは、インスタンスロケーションのキーが、インスタンスロケーションオブジェクト内のキーと一致する場合にのみ、インスタンスロケーションに適用されます。

インスタンスデータがオブジェクトであることを確認したい場合は、type キーワードを使用してください。

オブジェクトに "name" プロパティがあることを確認したい場合は、required キーワードを使用してください。

要約

JSON Schema が機能しないように見える最も一般的な理由は、完全に必要な制約が不足していることです。

JSON Schema は「制約ベース」であり、キーワードは正しいデータ型にのみ適用される場合があります。複数のキーワードを使用して制約を強化することで、タイプ固有のキーワードの不一致が別のキーワードによって処理されるようにすることができます。

サブスキーマを特定し、スキーマが常にブール値になり得ることを知ることで、正しい適用に関する前提を確認できます。サブスキーマは、必要に応じて常に単独でテストできます。

次のステップ / 参考文献

JSON Schema の基本的な理解を深める上で、この非常に簡単な入門が、JSON Schema の読み方、推論方法、開発方法の理解に役立つことを願っています。

現在 JSON Schema を作成するための私の推奨事項は、VSCode を使用することです。ファイルが JSON 言語モードの場合、ルートオブジェクトに $schema 値が追加されると、VSCode はオートコンプリートと IntelliSense を提供します (ただし、これは draft-07 に限定されます)。

以下は、今後役立つ可能性のある場所です。

写真提供:Saad Salim ( Unsplash )