Как проверить конкретную jsonschema на основе типа документа - PullRequest
0 голосов
/ 05 июня 2018

У меня есть схема JSON для нового сообщения пользователя:

message_creation = {
    "title": "Message",
    "type": "object",
    "properties": {
        "post": {
            "oneOf": [
                {
                    "type": "object",
                    "properties": {
                        "content": {
                            "type": "string"
                        }
                    },
                    "additionalProperties": False,
                    "required": ["content"]
                },
                {
                    "type": "object",
                    "properties": {
                        "image": {
                            "type": "string"
                        }
                    },
                    "additionalProperties": False,
                    "required": ["image"]
                },
                {
                    "type": "object",
                    "properties": {
                        "video_path": {
                            "type": "string"
                        }
                    },
                    "additionalProperties": False,
                    "required": ["video"]
                }
            ]
        },
        "doc_type": {
            "type": "string",
            "enum": ["text", "image", "video"]
        }
    },
    "required": ["post", "doc_type"],
    "additionalProperties": False
}

Все просто!Есть два поля: одно type, а другое post.Таким образом, полезная нагрузка, подобная приведенной ниже, выполняется успешно:

{
    "post": {
        "image": "Hey there!"
    },
    "type": "image"
}

Теперь проблема в том, что если пользователь устанавливает type значение на text, я не могу проверить, была ли задана текстовая схема.Как мне это проверить?Как мне проверить, если type установлено на image, а затем убедиться, что image существует внутри сообщения?

1 Ответ

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

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

{
  "type": "object",
  "properties": {
    "post": {
      "type": "object",
      "properties": {
        "content": { "type": "string" },
        "image": { "type": "string" },
        "video_path": { "type": "string" }
      },
      "additionalProperties": false
    },
    "doc_type": {
      "type": "string",
      "enum": ["text", "image", "video"]
    }
  },
  "required": ["post", "doc_type"],
  "additionalProperties": false,
  "allOf": [
    { "$ref": "#/definitions/image-requires-post-image" },
    { "$ref": "#/definitions/text-requires-post-content" },
    { "$ref": "#/definitions/video-requires-post-video-path" }
  ],
  "definitions": {
    "image-requires-post-image": {
      "anyOf": [
        { "not": { "$ref": "#/definitions/type-image" } },
        { "$ref": "#/definitions/post-image-required" }
      ]
    },
    "type-image": {
      "properties": {
        "doc_type": { "const": "image" }
      }
    },
    "post-image-required": {
      "properties": {
        "post": { "required": ["image"] }
      }
    },
    "text-requires-post-content": {
      "anyOf": [
        { "not": { "$ref": "#/definitions/type-text" } },
        { "$ref": "#/definitions/post-content-required" }
      ]
    },
    "type-text": {
      "properties": {
        "doc_type": { "const": "text" }
      }
    },
    "post-content-required": {
      "properties": {
        "post": { "required": ["content"] }
      }
    },
    "video-requires-post-video-path": {
      "anyOf": [
        { "not": { "$ref": "#/definitions/type-video" } },
        { "$ref": "#/definitions/post-video-path-required" }
      ]
    },
    "type-video": {
      "properties": {
        "doc_type": { "const": "video" }
      }
    },
    "post-video-path-required": {
      "properties": {
        "post": { "required": ["video_path"] }
      }
    }
  }
}
...