Json схема - не требуется не работает - PullRequest
1 голос
/ 28 февраля 2020

У меня есть случай, когда я проверяю требуемые свойства условно.

«не требуется» не работает должным образом.

Если «профиль» как профиль1, тогда поля «скорость», «трюк» и «тег» обязательны для заполнения, а «код», «имя» 'и' type 'не должны присутствовать.

Если' profile 'в качестве profile2, то' code 'требуется, а' rate ',' tag 'и' trick 'не требуются.

если «профиль» - это профиль3, тогда «скорость», «тег», «трюк», «код», «имя» и «тип» не требуются.

Я использую черновую версию схемы версии 4

Схема

{
  "type": "object",
  "properties": {
    "id": { "type": "integer" },
    "url": { "type": "string" },
    "profile": { "type": "string" },
    "rate": { "type": "string" },
    "trick": { "type": "boolean" },
    "tag": { "type": "string" },
    "type": { "type": "string" },
    "name": { "type": "string" },
    "code": { "type": "string" }
  },
  "additionalProperties": false,
  "required": [ "url", "profile" ],
  "oneOf": [
    {
      "properties": { "profile": { "enum": [ "profile1" ] } },
      "not": { "required": ["type", "name", "code"] }
    },
    {
      "properties": { "profile": { "enum": [ "profile2" ] } },
      "allOf": [
        { "required": [ "code" ] },
        { "not": { "required": ["rate", "tag", "trick"] } }
      ]
    },
    {
      "properties": { "profile": { "enum": ["profile3"] } },
      "not": { "required": ["rate", "trick", "tag", "type", "name", "code"] }
    }
  ]
}

Допустимые входы

{
  "id": 1,
  "url": "url",
  "profile": "profile2",
  "type": "",
  "name": "",
  "code": ""
}
{
  "id": 1,
  "url": "url",
  "profile": "profile3"
}
{
  "id": 1,
  "url": "url",
  "profile": "profile1",
  "rate": "",
  "trick": false,
  "tag": ""
}

Недопустимые входы

{
  "url": "url",
  "profile": "profile3",
  "code": ""
}

1 Ответ

1 голос
/ 28 февраля 2020

Я вижу, как вы пришли к этому подходу, и вы могли бы заставить его работать, но это не лучший подход.

Ключевое слово not инвертирует результат утверждения подсхемы значения.

Если вы берете anyOf[2].not схему ...

{ "required": ["rate", "trick", "tag", "type", "name", "code"] }

Это означает, что, как я уверен, вы знаете, все эти свойства обязательны.

not затем инвертирует результат применения этой подсхемы.

Поскольку в вашем примере объекта, который, как вы ожидаете, не пройдет проверку, у него будет только code из этого массива, тогда он не будет соответствовать required ограничение.

Можно сделать так, чтобы not > anyOf > [required > rate, required > trick... и c имели много подсхем, но это было бы немного некрасиво.

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

Ваш anyOf будет выглядеть следующим образом (демо: https://jsonschema.dev/s/zG9GF):

"anyOf": [
    false,
    false,
    {
      "properties": {
        "profile": {
          "const": "profile3",
          "id": true
        }
      },
      "additionalProperties": false
    }
  ]

Вы можете найти его больше идиоматических c для использования if/then/else ключевых слов из draft-07, а затем вы можете использовать allOf и установить для else значение false i Если вы не хотите иметь перечисление верхнего уровня для profile.

...