Ссылка на родительскую схему в подсхеме для проверки схемы JSON

Я работаю над схемой JSON, и я не уверен, правильно ли я ее разработал, и буду признателен за любые предложения.

Итак, у меня есть родительский объект с именем «Task.json», который ссылается на внутренний объект с именем «Data.json». Теперь мне нужен способ проверки схемы таким образом, чтобы требуемые свойства «Data.json» различались в зависимости от свойства из «Task.json». Например, если Task.json содержит «action = create», мы хотим, чтобы свойства в data.json были «a», «b» или «c», а «action = update» должны быть «a», «d». , "е". Я не уверен, как я могу ссылаться на родительский объект (действие) в data.json, чтобы иметь возможность указать допустимые свойства в зависимости от параметра «действие».

Пример:

Task.json

{
   "oneOf":[
      {
         "action":"create",
         "data":"data.json"
      },
      {
         "action":"update",
         "data":"data.json"
      }
   ]
}

Данные.json

      {
   "properties":{
      "a":{

      },
      "b":{

      },
      "d":{

      },
      "e":{

      }
   },
   "oneOf":[
      {
         "#/action":{
            "enum":[
               "create"
            ]
         },
         "required":[
            "a",
            "b",
            "c"
         ]
      },
      {
         "#/action":{
            "enum":[
               "update"
            ]
         },
         "required":[
            "a",
            "d",
            "e"
         ]
      }
   ]
}

person user5879804    schedule 22.12.2017    source источник


Ответы (2)


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

{
  "type": "object",
  "properties": {
    "action": { "enum": ["create", "update", "delete"] },
    "data": {
      "type": "object",
      "properties": {
        "a": {},
        "b": {},
        "d": {},
        "e": {}
      }
    }
  },
  "allOf": [
    { "$ref": "#/definitions/action-create-implies-abc" },
    { "$ref": "#/definitions/action-update-implies-ade" }
  ],
  "definitions": {
    "action-create-implies-abc": {
      "anyOf": [
        { "not": { "$ref": "#/definitions/action-create" } },
        {
          "properties": {
            "data": { "required": ["a", "b", "c"] }
          },
          "required": ["data"]
        }
      ]
    },
    "action-update-implies-ade": {
      "anyOf": [
        { "not": { "$ref": "#/definitions/action-update" } },
        {
          "properties": {
            "data": { "required": ["a", "d", "e"] }
          },
          "required": ["data"]
        }
      ]
    },
    "action-create": {
      "properties": {
        "action": { "enum": ["create"] }
      },
      "required": ["action"]
    },
    "action-update": {
      "properties": {
        "action": { "enum": ["update"] }
      },
      "required": ["action"]
    }
  }
}
person Jason Desrosiers    schedule 23.12.2017
comment
Итак, я попытался проверить приведенную выше схему, и, похоже, она игнорирует необходимые внутренние свойства определений. Просто для целей тестирования я обновил необходимое перечисление, а затем, похоже, проверил внутренние свойства anyOf. Похоже, что required не работает внутри определений/свойств. - person user5879804; 28.12.2017
comment
Я не уверен, что вы пытаетесь сказать. Но, похоже, это может быть отдельный вопрос? Лучший способ помочь мне — задать новый вопрос. - person Jason Desrosiers; 28.12.2017

Спасибо Джейсон! Ваш пример великолепен и заставляет меня переосмыслить первоначальный дизайн.

Итак, я только что добавил к нему еще один слой, где внутри Data.json есть «MetaData.json», а для «создания» требуются «Data.json» и «a», «b» и «c» в «Metadata.json». ", в то время как для обновления требуется только "Metadata.json" с "a", "d" и "e" по мере необходимости. В этом случае есть ли способ указать внутри определений/свойств, что обязательными свойствами data.metadata являются «a», «b» и «c»? Этот дизайн соответствует варианту использования, который может потребоваться только для операции «обновление» "metadata.json" для передачи.

Пример:

Данные.json

    {
   "properties":{
      "x":{

      },
      "y":{

      },
      "z":{

      },
"metadata": {
      $ref: "metadata.json"
}
   }

Метаданные.json

{
   "properties":{
      "a":{

      },
      "b":{

      },
      "d":{

      },
      "e":{

      }
}
person user5879804    schedule 26.12.2017