🗂
JSON Schema をバージョン管理する
JSON Schemaをバージョン管理したいことがあったのでメモしておきます。
完成後の利用イメージ
1行目にschemaVersionを記すことで、バリデーションするスキーマのバージョンを切り替えます。
バリデーション対象.yml
schemaVersion: 1.0.1
hogehoge: fugafuga
...以下略
ディレクトリ構造
root
├── meta.yml
└── schemas
├── v1.0.0
│ └── config.yml
├── v1.0.1
│ └── config.yml
└── v1.1.0
└── config.yml
という形式です。
meta.yml
このファイルに各バージョンのschemaを結合させます (これをprmdでいうメタファイルとします)。
meta.yml
---
$schema: http://json-schema.org/draft-07/schema#
title: meta schema
description: バージョン管理するためのスキーマの枠
id: meta
allOf:
- if:
properties:
schemaVersion:
const: 1.0.0
then:
allOf:
- $ref: "#/definitions/v1.0.0"
- if:
properties:
schemaVersion:
const: 1.0.1
then:
allOf:
- $ref: "#/definitions/v1.0.1"
- if:
properties:
schemaVersion:
const: 1.1.0
then:
allOf:
- $ref: "#/definitions/v1.1.0"
required:
- schemaVersion
properties:
schemaVersion:
type: string
enum:
- 1.0.0
- 1.0.1
- 1.1.0
description: スキーマのバージョン
allOf
などを用いることにより、結合してバージョン指定したときにそのバージョンのスキーマを強制します。
なお、バージョン番号として1.0
などを用いると浮動小数点数として扱われてしまうため、"1.0"
と記す必要があります。
config.yml
上の meta.yml
に結合されます。
ファイル名は用途に合わせてください。何でもいいです。
v1.0.0/config.yml
id: v1.0.0
title: ...
definitions:
foo: ...
bar:
type: object
properties:
foo:
$ref: "#/v1.0.0/definitions/foo" # バージョンをベタ書きする必要がある。改良したい
required: ...
additionalProperties: false
type: object
properties:
schemaVersion: # ここでも定義しないとエラーが出る。JSON Schemaの限界
type: string
baz: ...
生成コマンド
JSON Schemaの結合などに用いられるgem、prmdを濫用します (要Ruby)。もっといいCLIを開発しても良さそうです。
prmd combine -m meta.yml schemas/ -o combined.json
これにより、combined.json
にバージョン管理可能な JSON Schema が結合生成されます。
Discussion