1. 概要

JSON Schema は、 JSONObjectの形式と構造を検証するための宣言型言語です。 これにより、特別なプリミティブの数を指定して、有効なJSONオブジェクトがどのようになるかを正確に記述することができます。

JSON Schema 仕様は、次の3つの部分に分かれています。

  • JSON Schema Core :JSON Schema Core仕様では、スキーマの用語が定義されています。
  • JSONスキーマ検証:JSONスキーマ検証仕様は、検証制約を定義するための有効な方法を定義するドキュメントです。 このドキュメントでは、JSONAPIの検証を指定するために使用できる一連のキーワードも定義しています。 以下の例では、これらのキーワードのいくつかを使用します。
  • JSON Hyper-Schema :これはJSONスキーマ仕様の別の拡張であり、ハイパーリンクとハイパーメディア関連のキーワードが定義されています。

2. JSONスキーマの定義

JSONスキーマの使用目的を定義したので、JSONオブジェクトとそれに対応するJSONスキーマを作成してみましょう。

以下は、製品カタログを表す単純なJSONオブジェクトです。

{
    "id": 1,
    "name": "Lampshade",
    "price": 0
}

そのJSONスキーマは次のように定義できます。

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "Product",
    "description": "A product from the catalog",
    "type": "object",
    "properties": {
        "id": {
            "description": "The unique identifier for a product",
            "type": "integer"
        },
        "name": {
            "description": "Name of the product",
            "type": "string"
        },
        "price": {
            "type": "number",
            "minimum": 0,
            "exclusiveMinimum": true
        }
    },
    "required": ["id", "name", "price"]
}

ご覧のとおり、JSONスキーマJSONドキュメントであり、そのドキュメントはオブジェクトである必要があります。 JSON Schema で定義されたオブジェクトメンバー(またはプロパティ)は、キーワードと呼ばれます。

サンプルで使用したキーワードについて説明しましょう。

  • $ schema キーワードは、このスキーマがドラフトv4仕様に従って記述されていることを示しています。
  • titleおよびdescriptionキーワードは、検証されるデータに制約を追加しないという点で、説明的なものにすぎません。 スキーマの意図は、次の2つのキーワードで示されます。製品を説明します。
  • type キーワードは、JSONデータの最初の制約を定義します。JSONオブジェクトである必要があります。

また、JSONスキーマにはスキーマキーワードではないプロパティが含まれる場合があります。 この場合、 id name price は、 JSON Object のメンバー(またはプロパティ)になります。

プロパティごとに、typeを定義できます。 idnamestringpricenumberと定義しました。 JSON Schema では、数値に最小値を設定できます。 デフォルトでは、この最小値は包括的であるため、ExclusiveMinimumを指定する必要があります。

最後に、 Schema は、 id name 、およびpricerequiredであることを示します。

3. JSONスキーマによる検証

JSONスキーマを配置するとJSONオブジェクトを検証できます。

このタスクを実行するための多くのライブラリがあります。 この例では、Java json-schemaライブラリを選択しました。

まず、pom.xmlに次の依存関係を追加する必要があります。

<dependency>
    <groupId>org.everit.json</groupId>
    <artifactId>org.everit.json.schema</artifactId>
    <version>1.3.0</version>
</dependency>

最後に、 JSONオブジェクトを検証するための簡単なテストケースをいくつか作成できます:

@Test
public void givenInvalidInput_whenValidating_thenInvalid() throws ValidationException {
    JSONObject jsonSchema = new JSONObject(
      new JSONTokener(JSONSchemaTest.class.getResourceAsStream("/schema.json")));
    JSONObject jsonSubject = new JSONObject(
      new JSONTokener(JSONSchemaTest.class.getResourceAsStream("/product_invalid.json")));
    
    Schema schema = SchemaLoader.load(jsonSchema);
    schema.validate(jsonSubject);
}

この場合、スローされた ValidationException #/ priceを指します。コンソールを見ると、次の出力が出力されます。

#/price: 0.0 is not higher than 0

2番目のテストは次のようになります。

@Test
public void givenValidInput_whenValidating_thenValid() throws ValidationException {
    JSONObject jsonSchema = new JSONObject(
      new JSONTokener(JSONSchemaTest.class.getResourceAsStream("/schema.json")));
    JSONObject jsonSubject = new JSONObject(
      new JSONTokener(JSONSchemaTest.class.getResourceAsStream("/product_valid.json")));

    Schema schema = SchemaLoader.load(jsonSchema);
    schema.validate(jsonSubject);
}

有効なJSONオブジェクトを使用しているため、検証エラーはスローされません。

4. 結論

この記事では、JSONスキーマとは何か、そしてスキーマを定義するのに役立つ関連キーワードを定義しました

JSONSchemaを対応するJSONObject 表現と結合すると、いくつかの検証タスクを実行できます。

この記事の簡単なテストケースは、GitHubプロジェクトにあります。