Ajv не проверяет схему JSON при использовании «anyOf» с «requred»

#json #jsonschema #ajv

Вопрос:

У меня есть схема JSON, которая позволяет объекту иметь одно или несколько свойств:

 "properties": {
  "alpha": {
    "$ref": "#/$defs/alpha"
  },
  "beta": {
    "$ref": "#/$defs/beta"
  }
},
"anyOf": [
  {
    "required": [
      "alpha"
    ]
  },
  {
    "required": [
      "beta"
    ]
  }
]
 

При использовании ajv compile strict режима с включенным для проверки самой схемы проверка не выполняется. Как я могу это исправить?


Обновить

Похоже, это известная проблема, и в настоящее время ее невозможно обойти:


Я пробовал использовать anyOf properties , но, хотя эта схема проверяется, она работает не так, как предполагалось:

 "anyOf": [
  {
    "properties": {
      "alpha": {
        "$ref": "#/$defs/alpha"
      }
    },
    "required": [
      "alpha"
    ]
  },
  {
    "properties": {
      "beta": {
        "$ref": "#/$defs/beta"
      }
    },
    "required": [
      "beta"
    ]
  }
]
 
Команда Ajv
 ajv compile --spec=draft2020 --validate-formats=true --verbose --all-errors --strict=true -c ajv-formats -s repro.json
 
Ошибка Ajv
 schema repro.json is invalid
error: strict mode: required property "beta" is not defined at "repro.json#/anyOf/0" (strictRequired)
 
Полная схема JSON
 {
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$ref": "#/$defs/root",
  "$defs": {
    "root": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "alpha": {
          "$ref": "#/$defs/alpha"
        },
        "beta": {
          "$ref": "#/$defs/beta"
        }
      },
      "anyOf": [
        {
          "required": [
            "alpha"
          ]
        },
        {
          "required": [
            "beta"
          ]
        }
      ]
    },
    "alpha": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "foo": {
          "type": "string"
        }
      }
    },
    "beta": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "bar": {
          "type": "string"
        }
      }
    }
  }
}
 
Пример JSON
 {
  "alpha": {
    "foo": "xyz"
  }
}
 

Ответ №1:

Вам нужно отключить строгий режим, который считает, что любое required ключевое слово должно иметь смежное properties для этих свойств.

В качестве альтернативы вы можете переместить определения свойств в anyOf предложения, но вам придется повторить их оба с обеих сторон, что не так уж и здорово (в противном случае у вас могли бы присутствовать оба свойства, но одно из них не проверяется в соответствии с их схемой).

Так что попробуйте это:

   "$defs": {
    "root": {
      "type": "object",
      "anyOf": [
        {
          "required": [
            "alpha"
          ],
          "properties": {
            "alpha": {
              "$ref": "#/$defs/alpha"
            },
            "beta": {
              "$ref": "#/$defs/beta"
            }
          },
          "additionalProperties": false,
        },
        {
          "required": [
            "beta"
          ],
          "properties": {
            "alpha": {
              "$ref": "#/$defs/alpha"
            },
            "beta": {
              "$ref": "#/$defs/beta"
            }
          },
          "additionalProperties": false
        }
      ]
    }
  },
  ...
 

Комментарии:

1. Спасибо! Не могли бы вы привести anyOf пример? Моя попытка, как я уже упоминал, не сработала.

2. @beatcracker отредактировано.

3. Спасибо, к сожалению , в то время как пример вашей схемы проверяет strict=true , на самом деле он не проверяет входные данные: jsonschemavalidator.net/s/RWvtM82s

4. Данные по этой ссылке подтверждаются. В чем проблема?

5. Это не должно проверяться в соответствии со схемой: jsonschemavalidator.net/s/JspXqdWv