お仕事でPowerAutomateワークフローの構築・運用をする中でしばしばお世話になっているJSON Schema。直近その仕様を確認する機会があったので、その結果をご紹介。
PowerAutomateでは「JSONの解析」アクションでこのJSON Schemaを使用。ふつうは「サンプルから生成」機能で、既存のJSONを元に自動導出するはず。
ただサンプルはあくまでサンプル。実際にフローを実行してみると、サンプルベースのスキーマでは不十分で、自動導出されたスキーマに手を加えないとならないことも。
そうした時の参考になるかと。
JSON Schemaとは?
IETFという標準化団体のもとで標準化されているJSONデータの構造を定義するための言語。
構造定義によりJSONを用いたアプリケーション間のコミュニケーションの生産性・品質を向上させる。
AjaxやRESTfulAPIの普及とともにその必要性が生じ、近年ではシングルページアプリケーションのデファクト化やマイクロサービス化とともに重要度が上がっている状況。
Swagger(OpenAPI)でもJSON Schemaのサブセットが利用。
定義そのものがJSON形式で記述。
仕様には複数バージョンあり、スキーマ生成・解釈をする実装ごとにサポート状況に差がある点は要注意。
スキーマ例
次のようなJSONがあるとき、
{
"productId": 1,
"productName": "A green door",
"price": 12.50,
"tags": [ "home", "green" ]
}
そのスキーマは次のように表現される:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/product.schema.json",
"title": "Product",
"description": "A product from Acme's catalog",
"type": "object",
"properties": {
"productId": {
"description": "The unique identifier for a product",
"type": "integer"
},
"productName": {
"description": "Name of the product",
"type": "string"
},
"price": {
"description": "The price of the product",
"type": "number",
"exclusiveMinimum": 0
},
"tags": {
"description": "Tags for the product",
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"uniqueItems": true
}
},
"required": [ "productId", "productName", "price" ]
}
(参考ページより引用)
第1階層にはスキーマそのもののメタ情報($schema
、$id
、title
など)と、ルートとなるデータ型(type
)。
第2階層(properties
のプロパティ)にはオブジェクトのプロパティの定義情報。プロパティのデータ型もまたobject
の場合は入れ子構造でプロパティの定義情報が記述される。
データ型+α の表現力
JSON SchemaはJSONの仕様に定められたJSONのデータ型について記述することはもちろん、それらが特定のJSONデータにおいてどのように構造化されているかを定義。
さらにJSON仕様だけでは表現できないごとにさまざまなデータの制約も表現できる。
例えば、
型 | 型固有のキーワード | 説明 |
---|---|---|
array | items, minItems, maxItems, uniqueItems | 要素のスキーマ定義、要素数の制約、要素の一意性など |
number | minimum, maximum, exclusiveMinimum, exclusiveMaximum, multipleOf | 数値の範囲、倍数制限など |
object | required, properties, patternProperties, minProperties, maxProperties | 必須プロパティ、入れ子のプロパティ、正規表現によるプロパティマッチング、プロパティ数の制約など |
string | minLength, maxLength, pattern, format | 文字列長の制限、正規表現による制約、所定のフォーマットへの適合など |
参考ページ
JSONらしい柔軟な構造定義
JSONの特性はそのシンプルさと柔軟性。後者はメリットにもデメリットにもなる。アプリケーション間でJSONデータのやり取りするとき「存在する想定でいたプロパティが存在しない」「プロパティの型が想定していたものではない」といった問題が生じうる。
JSON Schemaにはこの「柔軟性」を定義するための構文やキーワードも存在。
例えば、
構文・キーワード | 説明 |
---|---|
"type": ["type1", "type2", ...] |
いずれかのデータ型に該当する |
"anyOf": [{ ... }, ...] |
サブスキーマのいずれかに該当する |
"not": {...} |
サブスキーマに該当しない |
required |
指定したプロパティが必ず存在する |
dependentrequired |
プロパティAが存在する場合、別のプロパティBやCも存在する |
"if": {...}, "then": {...},"else": {...} |
条件として指定したサブスキーマにマッチする場合としない場合とで、それぞれ別のサブスキーマにマッチするかを検証 |
null
もデータ型の1つである点に注意! null
値を取りうるプロパティはそのことをきちんとスキーマに表現する必要がある。"type": "string"
ではなく "type": ["string", "null"]
でないといけないということ。
さらに高度な検証
ここまでざっと見てきた以外にも、条件付きのスキーマ検証の定義や、取りうる値を列挙型や定数として制約、日時・日付・時刻・Eメールといったフォーマットの定義など、さらに高度な検証の助けとなる仕様も存在する。