JSON Свойства объекта переключения схемы на основе перечисления - PullRequest
0 голосов
/ 17 июня 2020

Я боролся с "переключателем" в схеме JSON. Пройден через пару обсуждений GitHub и SO по этому топи c, но не нашел решения. Я намерен изменить свойства объекта «полезная нагрузка» на основе перечисления «id», которое будет иметь 30 различных сопоставлений (определения «полезной нагрузки» для каждого перечисления «id»). Например, первый объект сообщения json будет иметь количество и другие свойства, но для демонстрационной цели давайте go только с одним свойством (amout):

{
"message": {
    "id": 1,
    "correlationId": "a0011e83-280e-4085-b0f1-691059aaae61",
    "payload": {
        "amount": 100
    }
}

}

И второе json:

{
"message": {
    "id": 2,
    "correlationId": "a0011e83-280e-4085-b0f1-691059aaae61",
    "payload": {
        "code": "xyz"
    }
}

}

Есть ли способ построить схему JSON (черновик 7 или любой другой) таким образом?

1 Ответ

0 голосов
/ 17 июня 2020

То, что вы просите, является довольно распространенным требованием. Использование oneOf / anyOf должно доставить вас туда, куда вы хотите.

В тех случаях, когда альтернативы являются взаимоисключающими (из-за разных значений id), я предпочитаю anyOf чтобы позволить валидатору схемы прекратить проверку при обнаружении первой совпадающей подсхемы - тогда как oneOf подразумевает, что все другие альтернативы не должны совпадать, например, в случае "id": 1 валидатору нужно будет только проверять первую подсхему в anyOf чтобы указать, что он действителен, в то время как для oneOf ему нужно будет проверить другие 29, чтобы убедиться, что они также недействительны. Но вы можете найти oneOf более выразительным для людей-потребителей вашей схемы.

Для вашего конкретного сценария я бы представил что-то вроде следующей схемы:

{
  "type": "object",
  "required": ["message"],
  "properties": {
    "message": {
      "type": "object",
      "required": ["id", "correlationId", "payload"],
      "properties": {
        "id": { "enum": [1, 2, 3] },
        "correlationId": { "type": "string" },
        "payload": { "type": "object" }
      },
      "anyOf": [
        {
          "properties": {
            "id": { "const": 1 },
            "payload": { "$ref": "#/definitions/payload1" }
          }
        },
        {
          "properties": {
            "id": { "const": 2 },
            "payload": { "$ref": "#/definitions/payload2" }
          }
        },
        {
          "properties": {
            "id": { "const": 3 },
            "payload": { "$ref": "#/definitions/payload3" }
          }
        },
      ]
    }
  },
  "definitions": {
    "payload1": {
      "type": "object",
      "required": ["amount"],
      "properties": {
        "amount": { "type": "integer" }
      }
    },
    "payload2": {
      "type": "object",
      "required": ["code"],
      "properties": {
        "code": { "type": "string" }
      }
    },
    "payload3": {
      "type": "object",
      "required": ["foo"],
      "properties": {
        "foo": { "type": "string" }
      }
    }
  }
}
...