JSON Schemaの意味や書き方を理解してバリテーションをかけよう!

みなさんこんにちは!今日はJSON Schemaについて話していこうと思います!

目次

JSON Schemaとは何か?

みなさん、そもそもJSON Schemaが何か、どういうものかということは知っていますか?JSON Schemaとは名前の通りJSON形式で書かれたSchemaのことです。

Schemaとはデータベースを扱うときによく出てくる単語ですが、簡単に言えば文書をある構造の元、定義したもののことです。Railsであれば、schema.rbに決まった構造でDBの内容を書いてあげれば読み込むことでDBを再現できます。

JSON SchemaにはJSON Hyper-SchemaとJSON Schema2つ種類があるので次項で紹介していきます。また、公式ドキュメントはこちらです。

JSON Schemaの特徴

公式ページをみてみると、JSON Schemaの特徴は、

  • 既存のデータを読み取ってくれる
  • 全てJSONで記述
  • 人間と機械が読みやすい
  • 送信するデータや、自動テストでのバリテーションが便利

とありますね。タイトルにもありますが、バリテーションとは入力内容にミスが無いかどうかチェックする行為のことを指します。

JSON Hyper-Schemaの特徴

JSON Hyper-Schemaと特徴は、

  • インスタンスデータとURI Templatesが共用できる
  • JSONスキーマからクライアントデータが記述できる

などですね。ここらへんについては詳しく理解する必要はありませんが、JSON Schemaを使うときは使うことによってどのようなメリットがあるのかを考えるようにしましょう。

JSON Schemaのメリット・デメリット

ここで、JSON Schemaのメリットとデメリットをまとめてみます。まずメリットですが、

  • バリテーションをかけることができる
  • テストを自動化できる
  • テスト用のサーバとして使える
  • APIドキュメントを作成できる

デメリットは、

  • JSONを書くのがだるい

といったところでしょうか。JSONをそのまま書くのは、ミスにつながり消耗するので、ymlで書いたものを変換するという方法が一般的です。

メリットは色々ありますが、全ては紹介しきれないので今日はまず最初に思いつくであろうバリテーションをかけるといったことを実際に行ってみましょう!

JSON Schemaを用意しよう!

まずは、JSON Schemaを用意していきましょう。テスト用にJSONデータは、こちらのサイトものを題材にしていきます。このサイトでサンプルのJSONデータをJSON Schemaにしていきましょう。

JSON

{
  "checked": false,
  "dimensions": {
    "width": 5,
    "height": 10
  },
  "id": 1,
  "name": "A green door",
  "price": 12.5,
  "tags": [
    "home",
    "green"
  ]
}

JSON Scheme

{
  "definitions": {},
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "http://example.com/root.json",
  "type": "object",
  "title": "The Root Schema",
  "required": [     "checked",     "dimensions",
     "id",
     "name",
     "price",
     "tags"
   ],
   "properties": {
     "checked": {
       "$id": "#/properties/checked",
       "type": "boolean",
       "title": "The Checked Schema",
       "default": false,
       "examples": [
         false
       ]
     },
     "dimensions": {
       "$id": "#/properties/dimensions",
       "type": "object",
       "title": "The Dimensions Schema",
       "required": [
         "width",
         "height"
       ],
       "properties": {
         "width": {
           "$id": "#/properties/dimensions/properties/width",
           "type": "integer",
           "title": "The Width Schema",
           "default": 0,
           "examples": [
             5
           ]
         },
         "height": {
           "$id": "#/properties/dimensions/properties/height",
           "type": "integer",
           "title": "The Height Schema",
           "default": 0,
           "examples": [
             10
           ]
         }
       }
     },
     "id": {
       "$id": "#/properties/id",
       "type": "integer",
       "title": "The Id Schema",
       "default": 0,
       "examples": [
         1
       ]
     },
     "name": {
       "$id": "#/properties/name",
       "type": "string",
       "title": "The Name Schema",
       "default": "",
       "examples": [
         "A green door"
       ],
       "pattern": "^(.*)$"
     },
     "price": {
       "$id": "#/properties/price",
       "type": "number",
       "title": "The Price Schema",
       "default": 0.0,
       "examples": [
         12.5
       ]
     },
     "tags": {
       "$id": "#/properties/tags",
       "type": "array",
       "title": "The Tags Schema",
       "items": {
         "$id": "#/properties/tags/items",
         "type": "string",
         "title": "The Items Schema",
         "default": "",
         "examples": [
           "home",
           "green"
         ],
         "pattern": "^(.*)$"
       }
     }
   }
 }

少し長くてみにくいので、スッキリさせます。

"definitions": {},
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
     "checked",
     "id",
     "name",
     "price",
     "tags"
   ],
   "properties": {
     "checked": {
       "$id": "#/properties/checked",
       "type": "boolean",
       "title": "The Checked Schema"
     },
     "id": {
       "examples": [
         1
       ]
     },
     "name": {
       "examples": [
         "A green door"
       ],
       "pattern": "^(.*)$"
     },
     "price": {
       "examples": [
         12.5
       ]
     },
     "tags": {
         "examples": [
           "home",
           "green"
         ],
         "pattern": "^(.*)$"
       }
     }
   }

それではこちらのJSON Schemaを題材にバリテーションをかけていきましょう!

JSON Schemaにバリテーションをかけてよう!

さて、実際にバリテーションをかけていくわけですが、今回はPythonを使います!JSONで書かれたバリテーションを行う場合、かなり面倒ですよね。

ただでさえ情報量が多く可読性が低いJSONでネストされていたりいたらもう最悪ですよね。なので、今日はこの面倒な作業を簡単にしてくれるjsonschemaというPythonのパッケージを使っていきます。まずは、インストールしましょう。

pip install jsonschema

次は、コードをみていきましょう。

import jsonschema

origin_data = {
  "definitions": {},
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
     "checked",
     "id",
     "name",
     "price",
     "tags"
   ],
   "properties": {
     "checked": {
     },
     "id": {
       "examples": [
         1
       ]
     },
     "name": {
       "examples": [
         "A green door"
       ],
       "pattern": "^(.*)$"
     },
     "price": {
       "examples": [
         12.5
       ]
     },
     "tags": {
         "examples": [
           "home",
           "green"
         ],
         "pattern": "^(.*)$"
       }
     }
   }


check_data = {
  "id": 2,
  "name": "A green door",
  "price": 12.5,
  "checked": False,
  "tags": [
    "home",
    "green"
  ]
}

jsonschema.validate(check_data, origin_data)

origin_dataにJSON Schemaに格納し、check_dataにチェックするためのデータを導入します。6行目に”required”されている内容が書いてあるので、その内容を含むチェックデータを導入します。実行すると、何も起きませんのでこれで正常です。

では、”price"がrequiredされているのにチェックデータに導入しなかったらどうなるでしょうか。

check_data = {
  "id": 2,
  "name": "A green door",
  #"price": 12.5,
  "checked": False,
  "tags": [
    "home",
    "green"
  ]
}

このように、priceを消して実行すると、

line 130, in validate
    raise error
jsonschema.exceptions.ValidationError: 'price' is a required property

Failed validating 'required' in schema:

このようにpriceがないよ、とバリテーションしてくれていますね。

まとめ

いかがでしたか。今日は、

  • JSON Schemaとは何か
  • どんなメリットがあるのか
  • JSON SchemaのバリテーションをPythonで書く

ということを行いました。JSON Schemaは現代のコンテナブームを考えると使えるようになっておくスキルですので是非マスターしておきましょう!それでは!!

この記事を書いた人

【プロフィール】
DX認定取得事業者に選定されている株式会社SAMURAIのマーケティング・コミュニケーション部が運営。「質の高いIT教育を、すべての人に」をミッションに、IT・プログラミングを学び始めた初学者の方に向け記事を執筆。
累計指導者数4万5,000名以上のプログラミングスクール「侍エンジニア」、累計登録者数1万8,000人以上のオンライン学習サービス「侍テラコヤ」で扱う教材開発のノウハウ、2013年の創業から運営で得た知見に基づき、記事の執筆だけでなく編集・監修も担当しています。
【専門分野】
IT/Web開発/AI・ロボット開発/インフラ開発/ゲーム開発/AI/Webデザイン

目次