Использовать json-схему, чтобы требовать или запрещать свойства на основе другого значения свойства? - PullRequest
0 голосов
/ 15 мая 2018

То, что я пытаюсь выполнить в json-схеме: когда свойство enabled равно true, должны потребоваться некоторые другие свойства.Когда false, эти свойства должны быть запрещены.

Вот моя json-схема:

{
  "type": "object",
  "properties": {
    "enabled": { "type": "boolean" }
  },
  "required" : ["enabled"],
  "additionalProperties" : false,
  "if": {
    "properties": {
      "enabled": true
    }
  },
  "then": { 
    "properties": {
      "description" : { "type" : "string" },
      "count": { "type": "number" }
    },
    "required" : ["description", "count"]
  }
}

Проверка с использованием ajv версии 6.5, в результате потребовалось count и т. Д. Независимо от значения enabled.Например, для данных:

{ "enabled": false }

Мои ошибки валидации:

[ { keyword: 'required',
    dataPath: '',
    schemaPath: '#/then/required',
    params: { missingProperty: 'description' },
    message: 'should have required property \'description\'' },
  { keyword: 'required',
    dataPath: '',
    schemaPath: '#/then/required',
    params: { missingProperty: 'count' },
    message: 'should have required property \'count\'' },
  { keyword: 'if',
    dataPath: '',
    schemaPath: '#/if',
    params: { failingKeyword: 'then' },
    message: 'should match "then" schema' } ]

Как я могу это сделать, используя json-схему draft-7?

Обратите внимание, чтоэтот вопрос похож, но имеет более строгие требования, чем:
атрибут jsonSchema, условно обязательный .

Ответы [ 3 ]

0 голосов
/ 15 мая 2018

Это было вдохновлено превосходным ответом vearutop.Я думаю, что это может быть немного короче и выполняет мою заявленную цель.

{
  "type": "object",
  "oneOf" : [
    {
      "properties": {
        "enabled": { "const": false }
      },
      "required": ["enabled"],
      "additionalProperties": false
    },
    {
      "properties": {
        "enabled": { "const": true },
        "description": { "type": "string" },
        "count": { "type": "number" }
      },
      "required": [ "enabled", "description", "count"],
      "additionalProperties": false
    }
  ]
}

Как указано в комментариях, это конкретный вариант стратегии Enum , изложенной в этот ответ .

0 голосов
/ 01 июня 2018

Для этого в операторе if необходимо использовать ключевое слово const, чтобы схема выглядела следующим образом:

{
  "type": "object",
  "properties": {
    "enabled": { "type": "boolean" }
  },
  "required" : ["enabled"],
  "additionalProperties" : false,
  "if": {
    "properties": {
      "enabled": {"const": true}
    }
  },
  "then": { 
    "properties": {
      "description" : { "type" : "string" },
      "count": { "type": "number" }
    },
    "required" : ["description", "count"]
  }
}
0 голосов
/ 15 мая 2018

Попробуйте эту схему:

{
  "type": "object",
  "properties": {
    "enabled": {
      "type": "boolean"
    }
  },
  "required": [
    "enabled"
  ],
  "if": {
    "properties": {
      "enabled": {
        "const": true
      }
    }
  },
  "then": {
    "properties": {
      "enabled": {
        "type": "boolean"
      },
      "description": {
        "type": "string"
      },
      "count": {
        "type": "number"
      },
      "additionalProperties": false
    },
    "required": [
      "description",
      "count"
    ]
  },
  "else": {
    "properties": {
      "enabled": {
        "type": "boolean"
      }
    },
    "additionalProperties": false
  }
}

Если вам нужно "additionalProperties": false, вам нужно перечислить все свойства как then, так и else.Если вы можете принять дополнительные свойства, схема может быть проще:

{
  "type": "object",
  "properties": {
    "enabled": {
      "type": "boolean"
    }
  },
  "required": [
    "enabled"
  ],
  "if": {
    "properties": {
      "enabled": {
        "const": true
      }
    }
  },
  "then": {
    "properties": {
      "description": {
        "type": "string"
      },
      "count": {
        "type": "number"
      }
    },
    "required": [
      "description",
      "count"
    ]
  }
}

Я проверил с помощью ajv cli .

Действительный: {"enabled": false}

Неверный: {"enabled": true}

Действительный: {"enabled": true, "description":"hi", "count":1}

...