Python で、JSON Schema Validation

API の body リクエストの内容を jsonschema ライブラリを使って、簡単にチェックしよう

Kunihiko Kido
Aug 25, 2017 · 7 min read

こんにちは、クニです。写真は、嬬恋にキャンプに行った時に、草津温泉を訪れた時の1枚です。

さて、API の開発をしていると JSON を body で受け付けて、ごにょごにょする機会が多いのではないでしょうか?

CURD を提供する REST API であれば、JSON のバリデーションチェックも比較的簡単に実装できるようにフレームワークで用意されています。しかし、全文検索用の API を実装しようとすると自前で、必須属性のチェックや型チェックなど実装することが多いように思います。

今回は、Python の jsonschema パッケージを紹介します。

それではさっそく。

インストール

まずは、インストールです。

$ pip install jsonschema

実装するもの

jsonschema の使い方について説明します。まず、想定する JSON データは以下です。https://jsonschema.net/ のサンプルデータでを使います。

{
"id": 1,
"name": "A green door",
"price": 12.5,
"checked": false,
"tags": [
"home",
"green"
]
}

jsonschema.net は、JSON のサンプルデータから JSON Schema を生成してくれるツールです。このツールを使って、以下の JSON Schema を作成しました。

{
"$schema": "http://json-schema.org/draft-04/schema#",
"properties": {
"checked": {
"type": "boolean"
},
"id": {
"type": "integer"
},
"name": {
"type": "string"
},
"price": {
"type": "number"
},
"tags": {
"items": {
"type": "string"
},
"type": "array"
}
},
"required": [
"id",
"name"
],
"type": "object"
}

それぞれのフィールドは型や構造が決まっています。また、idname フィールドは必須フィールドです。このルールで JSON のバリデーションチェックを実現していきましょう。

バリデーションチェック

自前で、JSON のバリデーションチェックを実装する場合、フィールド名や型、必須かどうかなどいろいろチェックする必要がありかなり面倒です。さらに JSON は、ネストされた構造も表現できるので、バリデーションチェックのコードだけでもかなりの実装量になってしまいます。ただルールに従っている内容かどうか確認するだけなのに。。

jsonschema の Python パッケージはこの面倒なロジックを簡略化してくれます。さらに、使用するルールセットは、先ほど作成した JSON Schema をそのまま使用できるのです。

便利ですよね?

使い方は非常に簡単です。まず、インストールした jsonschema モジュールをインポートします。

import jsonschema

次に

JSON Schema を Python オブジェクトとして変数に格納します。

schema = {
"$schema": "http://json-schema.org/draft-04/schema#",
"properties": {
"checked": {
"type": "boolean"
},
"id": {
"type": "integer"
},
"name": {
"type": "string"
},
"price": {
"type": "number"
},
"tags": {
"items": {
"type": "string"
},
"type": "array"
}
},
"required": [
"id",
"name"
],
"type": "object"
}

チェックしたい JSON を Python オブジェクトで用意します。

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

実行してみましょう。

jsonschema.validate(data, schema)

何も発生しませんでしたよね?ルールに従った正しい JSON の場合は、実行しても何も発生しません。

では、必須になっている id フィールドをコメントアウトして、サイド validator を実行してください。

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

ルールに従ってない場合は、ValidationError が発生します。

Traceback (most recent call last):

なんだかよくわからないメッセージなので、try/catch で Exception をハンドリングして、メッセージを表示します。

try:
jsonschema.validate(data, schema)
except jsonschema.ValidationError as e:
print('Invalid JSON - {0}'.format(e.message))

メッセージを表示すると、ちゃんと id フィールドは必須であることがメッセージで表示されますね。

Invalid JSON - 'id' is a required property

tags フィールドは、文字列の配列で定義していますが、文字列(”home”)を渡すと、 配列じゃないよ!と怒られました。

Invalid JSON - 'home' is not of type 'array'

まとめ

いかがでしたでしょうか? jsonschema を使うと、比較的簡単に JSON のバリデーションをチェックできますね。しかも、言語に依存しない JSON Schema の規格を使用できるのでおすすめです。

VELTRA Engineering

Posts from the VELTRA Engineering team. www.veltra.com

)

Thanks to Takuo Oki

Kunihiko Kido

Written by

木戸 国彦

VELTRA Engineering

Posts from the VELTRA Engineering team. www.veltra.com

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade