OneOf inside Json-Schema 选择一种情况及其否定

OneOf inside Json-Schema picks up one case and its negation

我使用如下所示的 Json-schema。它由两个定义组成,requestresponse.

如果 request 无效,则不允许 response。但如果 request 有效,则应有 response.

这里有两个 json 我认为可行的例子:

{
  "request": { "valid": true },
  "response":
  {
    "uuid": "12345678901234567890123456789012",
    "datetime": "123456789012345678901234",
    "seconds": 10
  }
}

{
  "request": { "valid": false }
}

我在问为什么 oneOf 没有按预期工作?一个 json 文件,如

{
  "request": { "valid": true }
}

验证为正确,即使没有它的请求部分。

架构:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "request": {
      "type": "object",
      "properties": {
        "valid": {
          "type": "boolean",
          "description": "Request was valid or not."
        }
      },
      "required": ["valid"],
      "additionalProperties": false
    },
    "response": {
      "type": "object",
      "properties": {
        "uuid": {
          "type": "string",
          "description": "UUID of person which logged in.",
          "maxLength": 36
        },
        "datetime": {
          "type": "string",
          "description": "Datetime of last interaction.",
          "maxLength": 24
        },
        "seconds": {
          "type": "integer",
          "description": "Login valid in seconds.",
          "minimum": 0
        }
      },
      "required": ["uuid", "datetime", "seconds"],
      "additionalProperties": false
    }
  },
  "title": "login response",
  "type": "object",
  "oneOf": [{
      "properties": {
        "request": {
          "valid": {
            "const": false
          }
        }
      },
      "required": ["request"],
      "additionalProperties": false
    },
    {
      "properties": {
        "request": {
          "valid": {
            "const": true
          }
        },
        "response": {
          "$ref": "#/definitions/response"
        }
      },
      "required": ["request", "response"],
      "additionalProperties": false
    }
  ]
}

您的 request 属性 似乎没有在 oneOf 中正确定义。这里有两个可能的解决方案来解决这个问题。希望对你有帮助。

解决方案 01:request 定义移动到每个 oneOf 块中

 "oneOf": [
    {
      "properties": {
        "request": {
          "type": "object",
          "properties": {
            "valid": {
              "const": false
            },
            "required": [
              "valid"
            ],
            "additionalProperties": false
          }
        }
      },
      "required": [
        "request"
      ],
      "additionalProperties": false
    },
    {
      "properties": {
        "request": {
          "type": "object",
          "properties": {
            "valid": {
              "const": true
            },
            "required": [
              "valid"
            ],
            "additionalProperties": false
          }
          }
        },
        "response": {
          "$ref": "#/definitions/response"
        }
      },
      "required": [
        "request",
        "response"
      ],
      "additionalProperties": false
    }
  ]

解决方案 02:request

使用单独的定义
 "definitions": {
    "valid_request": {
      "type": "object",
      "properties": {
        "valid": {
          "const": true,
          "description": "Request was valid"
        }
      },
      "required": [
        "valid"
      ],
      "additionalProperties": false
    },
    "invalid_request": {
      "type": "object",
      "properties": {
        "valid": {
          "const": false,
          "description": "Request was invalid"
        }
      },
      "required": [
        "valid"
      ],
      "additionalProperties": false
    }
 }
"oneOf": [
    {
      "properties": {
        "request": {
          "$ref": "#/definitions/invalid_request"
        }
      },
      "required": [
        "request"
      ],
      "additionalProperties": false
    },
    {
      "properties": {
        "request": {
          "$ref": "#/definitions/valid_request"
        },
        "response": {
          "$ref": "#/definitions/response"
        }
      },
      "required": [
        "request",
        "response"
      ],
      "additionalProperties": false
    }
  ]

问题是您的模式检查是否有效 true/false。请参见下面示例中的 #/definitions/is-valid-request。在这种情况下,我建议使用 if/then/else 而不是 oneOf。这样您将获得更多有用的错误消息。下面是您如何实施它的示例。

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "login response",
  "type": "object",
  "properties": {
    "request": { "$ref": "#/definitions/request" },
    "response": { "$ref": "#/definitions/response" }
  },
  "additionalProperties": false,
  "required": ["request"],
  "allOf": [{ "$ref": "#/definitions/require-response-with-valid-request" }],
  "definitions": {
    "request": { ... },
    "response": { ... },
    "require-response-with-valid-request": {
      "if": { "$ref": "#/definitions/is-valid-request" },
      "then": { "required": ["response"] },
      "else": { "not": { "required": ["response"] } }
    },
    "is-valid-request": {
      "properties": {
        "request": {
          "properties": {
            "valid": { "const": true }
          },
          "required": ["valid"]
        }
      },
      "required": ["request"]
    }
  }
}