Python で、JSON Schema Validation
API の body リクエストの内容を jsonschema ライブラリを使って、簡単にチェックしよう
こんにちは、クニです。写真は、嬬恋にキャンプに行った時に、草津温泉を訪れた時の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"
}
それぞれのフィールドは型や構造が決まっています。また、id
、 name
フィールドは必須フィールドです。このルールで 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"
]
}jsonschema.validate(data, schema)
ルールに従ってない場合は、ValidationError が発生します。
Traceback (most recent call last):File "<stdin>", line 1, in <module>File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/jsonschema/validators.py", line 541, in validatecls(schema, *args, **kwargs).validate(instance)File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/jsonschema/validators.py", line 130, in validateraise errorjsonschema.exceptions.ValidationError: 'id' is a required propertyFailed validating 'required' in 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'}On instance:{'checked': False,'name': 'A green door','price': 12.5,'tags': ['home', 'green']}
なんだかよくわからないメッセージなので、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 の規格を使用できるのでおすすめです。