Try   HackMD

JSONスキーマを使ってみる

tags: json

JSONスキーマ

JSONの整形

JSONスキーマの生成

JSONスキーマによる検証

JSONデータ

サンプルとなるJSONデータはこんな感じ。

{ "bookmarks": [ { "url": "https://www1.example.com", "title": "Title1", "description": "Description1", "datetime": "2020-01-01T11:11:11Z" }, { "url": "https://www2.example.com", "title": "Title2", "description": "Description2", "datetime": "2020-02-02T22:22:22Z" } ] }

JSONスキーマの生成

JSONデータからJSONschema.Netでスキーマを生成する。このスキーマはJSONデータの構造をそのままなぞった構造になっている。

{ "definitions": {}, "$schema": "http://json-schema.org/draft-07/schema#", "$id": "http://example.com/root.json", "type": "object", "title": "The Root Schema", "required": [ "bookmarks" ], "properties": { "bookmarks": { "$id": "#/properties/bookmarks", "type": "array", "title": "The Bookmarks Schema", "items": { "$id": "#/properties/bookmarks/items", "type": "object", "title": "The Items Schema", "required": [ "url", "title", "description", "datetime" ], "properties": { "url": { "$id": "#/properties/bookmarks/items/properties/url", "type": "string", "title": "The Url Schema", "default": "", "examples": [ "https://www1.example.com" ], "pattern": "^(.*)$" }, "title": { "$id": "#/properties/bookmarks/items/properties/title", "type": "string", "title": "The Title Schema", "default": "", "examples": [ "Title1" ], "pattern": "^(.*)$" }, "description": { "$id": "#/properties/bookmarks/items/properties/description", "type": "string", "title": "The Description Schema", "default": "", "examples": [ "Description1" ], "pattern": "^(.*)$" }, "datetime": { "$id": "#/properties/bookmarks/items/properties/datetime", "type": "string", "title": "The Datetime Schema", "default": "", "examples": [ "2020-01-01T11:11:11Z" ], "pattern": "^(.*)$" } } } } } }

JSONスキーマによるJSONデータの検証

JSON Schema validation onlineによる検証

JSON Schema validation onlineにおいてこのJSONデータをこのJSONスキーマにより検証してみると確かに成功する。$idとかexamplesなどがunknownとかignoredとなっているのが気になる。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

JSON Schema Validatorによる検証

JSONスキーマ自体の検証

JSONスキーマ自体もJSONであるから検証可能である。JSON Schema Validatorには有名どころのJSONスキーマがいくつか登録されており、その中にはJSONスキーマ自体のJSONスキーマも登録されている。生成されたJSONスキーマを検証すると成功する。ただしこれをもって正しく機能するJSONスキーマであるということはできない。例えば$refで参照する先が無かったとしてもそのような誤りの有無は検証できない。

JSONスキーマのJSONスキーマを見るとdefinitionsが宣言されている。definitionsの代わりにaiueoと書いたとしてもそれが$refで正しく参照されていればそのJSONスキーマを使って検証ができるのだが、やはりdefinitionsを使うのが正しいようだ。このような点を厳しく検証したいならば、JSONスキーマのJSONスキーマにあえて "additionalProperties":false を指定すれば検証においてエラーとなる。

JSONスキーマでよく使う宣言

必須のプロパティ

オブジェクトが持つべき必須のプロパティはrequiredで宣言する。自動的に作成されたJSONスキーマにもあるので特にこれ以上は書かない。

複数の型を取りうるプロパティ

"type"="object"とすればそのプロパティの取りうる値をオブジェクトに限定することを宣言する。"type"=["object","null","boolean"]などとすることもできる。JavaScriptと異なり、nullはオブジェクトではない。

追加のプロパティ

追加可能なプロパティを宣言するためにはadditionalPropertiesを使う。"additionalProperties"=falseすればJSONスキーマで宣言しなかったプロパティを禁止することになる。

スキーマ内での$ref

JSONスキーマの階層が深すぎるので、いくつかの宣言をJSONスキーマのルート直下のdefinitionsプロパティ以下に移動し$refで参照する。

{ "definitions": { "url": { "type": ["string", "null"] }, "title": { "type": ["string", "null"] }, "description": { "type": ["string", "null"] }, "datetime": { "type": ["string", "null"] } }, "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "required": ["bookmarks"], "properties": { "bookmarks": { "type": "array", "items": { "type": "object", "required": ["url", "title", "description", "datetime"], "properties": { "url": { "$ref": "#/definitions/url" }, "title": { "$ref": "#/definitions/title" }, "description": { "$ref": "#/definitions/description" }, "datetime": { "$ref": "#/definitions/datetime" } }, "additionalProperties": false } } } }

bookmarksがとる値はオブジェクトのリストと宣言されているが、この宣言もbookmarkとして分離できる。

{ "definitions": { "url": { "type": ["string", "null"] }, "title": { "type": ["string", "null"] }, "description": { "type": ["string", "null"] }, "datetime": { "type": ["string", "null"] }, "bookmark": { "type": "object", "required": ["url", "title", "description", "datetime"], "properties": { "url": { "$ref": "#/definitions/url" }, "title": { "$ref": "#/definitions/title" }, "description": { "$ref": "#/definitions/description" }, "datetime": { "$ref": "#/definitions/datetime" } }, "additionalProperties": false } }, "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "required": ["bookmarks"], "properties": { "bookmarks": { "type": "array", "items": { "$ref": "#/definitions/bookmark" } } } }

$refを使ったJSONスキーマでも検証に成功する。

外部のJSONスキーマの$refによる参照

JSONスキーマが長くて読みにくいので、definitionsgistに移動した。参照先にはdefinitions以外のプロパティが無いのでルートに移動した。これに伴い相対URLであった$refを絶対URLに変更した。URLはgistのraw URLを使った。

{
"definitions": {
"url": {
"type": ["string", "null"]
},
"title": {
"type": ["string", "null"]
},
"description": {
"type": ["string", "null"]
},
"datetime": {
"type": ["string", "null"]
},
"bookmark": {
"type": "object",
"required": ["url", "title", "description", "datetime"],
"properties": {
"url": {
"$ref": "#/definitions/url"
},
"title": {
"$ref": "#/definitions/title"
},
"description": {
"$ref": "#/definitions/description"
},
"datetime": {
"$ref": "#/definitions/datetime"
}
},
"additionalProperties": false
}
}
}
view raw external.json hosted with ❤ by GitHub

{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "required": ["bookmarks"], "properties": { "bookmarks": { "type": "array", "items": { "$ref": "https://gist.githubusercontent.com/TakashiSasaki/928eee5994217dfeea687d482338a70b/raw/external.json#/definitions/bookmark" } } } }

おまけ,空のJSONスキーマ

{}という空のJSONスキーマも立派(?)なJSONスキーマである。どんなJSONデータを検証しても成功する。

JSON Schema validation onlineによる検証

JSON Schema Validatorによる検証