Lambdaカクテル

京都在住Webエンジニアの日記です

JSON Schemaメモ: additionalProperties: falseのobject同士は,allOfで合体できない

このスキーマ中の#abは無効になる。https://www.jsonschemavalidator.net/で検証してみるとよい。

{
    "definitions": {
        "a": {
            "$id": "#a",
            "additionalProperties": false,
            "type": "object",
            "required": ["a"],
            "properties": {
                "a": { "type": "number" }
            }
        },
        "b": {
            "$id": "#b",
            "additionalProperties": false,
            "type": "object",
            "required": ["b"],
            "properties": {
                "b": { "type": "number" }
            }
        },
        "ab": {
            "$id": "#ab",
            "allOf": [{ "$ref": "#a" }, { "$ref": "#b" }]
        }
    },
    "$schema": "http://json-schema.org/draft-07/schema#",
    "$ref": "#ab"
}

additionalProperties: falseは強い効力を持っている。これがあるとallOfで他のオブジェクトと合体させることも禁止される。全てが強い効力を持っていて,いい感じに上書きする,ということはできなそう。どちらかのadditionalPropertiestrueにする(デフォルトでtrueだ)と,このスキーマは通る。やっぱり通らなかった。

aの場合はこのプロパティしか持っていてほしくないのだが,特定の場合にはこのプロパティも生える,といったことを表現したいときは,どっちもtrueにしないといけない。

なんでこういうことになったか

基本となる型Aとそれを元にいくつかのプロパティを追加した型A'みたいなのを作りたかったため。またAにいくつかの制約を課す代わりにプロパティが増える,みたいなことをやりたかったため。

やりよう

最上位でadditionalProperties: falseにし,全てのプロパティを明に示す(ただし,型は宣言しなくてよい)とやりたいことは実現できる。けどプロパティを全部列挙するの面倒だな。

{
    "definitions": {
        "a": {
            "$id": "#a",
            "additionalProperties": true,
            "type": "object",
            "required": ["a"],
            "properties": {
                "a": { "type": "number" }
            }
        },
        "b": {
            "$id": "#b",
            "additionalProperties": true,
            "type": "object",
            "required": ["b"],
            "properties": {
                "b": { "type": "number" }
            }
        },
        "ab": {
            "$id": "#ab",
            "additionalProperties": false,
            "properties": { "a": {}, "b": {} },
            "allOf": [{ "$ref": "#a" }, { "$ref": "#b" }]
        }
    },
    "$schema": "http://json-schema.org/draft-07/schema#",
    "$ref": "#ab"
}