У вашей схемы есть две основные проблемы: как вы используете if
- then
- else
и как вы используете addtionalProperties
.
if
- then
- else
JSON Ключевые слова схемы могут появляться только в контексте схемы. properties
определяет объект, значения которого являются схемой. properties
сам по себе не является схемой.
"properties": {
"foo": { ... }
"if": { ... },
"then": { ... }
}
Это не определяет одно свойство, "foo", плюс условное. Он определяет три свойства: «foo», «if», «then». Вам нужно довести условный уровень до уровня, чтобы он был распознан валидатором.
"properties": {
"foo": { ... }
},
"if": { ... }
"then": { ... }
В противном случае вы правильно используете if
- then
- else
. Это просто не в том месте.
additionalProperties
Как только вы получите if
- then
- else
в нужном месте, вы заметите, что вы получаете куча additionalProperties
ошибок. additionalProperties
может учитывать только ключевые слова properties
и patternProperties
в одном и том же месте схемы.
{
"allOf": [
{
"properties": {
"foo": { ... }
}
},
{
"properties": {
"bar": { ... }
},
"additionalProperties": false
}
]
}
/allOf/1/additionalProperties
может учитывать только /allOf/1/properties
, а не /allOf/0/properties
, Таким образом, { "foo": 1, "bar": 2 }
будет недействительным, потому что "foo" не определено в /allOf/1/properties
.
Есть несколько способов справиться с этим. Предпочтительный способ - просто не использовать additionalProperties
. Игнорируйте дополнительные свойства вместо того, чтобы запрещать их. Это лучше всего подходит для развивающихся схем, но в зависимости от домена это не всегда возможно.
Чтобы эффективно использовать additionalProperties
, вам нужны все возможные имена свойств под одним и тем же ключевым словом properties
.
"properties": {
"foo": { ... },
"bar": { ... }
},
"required": ["foo"],
"additionalProperties": false,
"if": {
"properties": {
"foo": { "const": 1 }
},
"required": ["foo"]
},
"then": { "required": ["bar"] }
Это один из возможных подходов. «bar» ожидается только в том случае, если «foo» равен 1, но «bar» определен в верхней части и требуется только в случае выполнения условия. Это не только заставляет additionalProperties
работать так, как вы ожидаете, его также легче читать, потому что все определения свойств находятся в одном месте, а условные схемы минимальны.
В этот момент вы можете быть обеспокоены тем, что включение «bar», когда «foo» не равно 1, не выдает ошибку. Опять же, я бы посоветовал вам игнорировать дополнительное свойство, а не запрещать его, если ваш домен позволяет. Но, если вам действительно нужно, вы можете использовать else
, чтобы запретить дополнительное поле.
"else": { "not": { "required": ["bar"] } }
Будьте осторожны, чтобы не перепутать слова в этой схеме. Это не означает «не требуется», что звучит как «необязательный», это означает «запрещено».