如何使用 anyOf 验证嵌套属性

How do I validate nested properties using anyOf

我正在努力使用 json-schema 编写验证规则。这是我的 json 格式的数据:

{
    "headers" : {
        "api_key" : "aaa-bbb-ccc-ddd-eee"
    },
    "query_string" : {
        "apikey" : "aaa-bbb-ccc-ddd-eee"
    }
}

我需要一条规则:

At least "headers->api_key" or "query_string->apikey" needs to be present in the json, but not both.

到目前为止,这是我的架构验证:

{
  "title": "Application Get Single",
  "type": "object",
  "properties": {
    "headers": {
      "type": "object",
      "properties": {
        "api_key": {
          "type": "string"
        }
      }
    },
    "query_string": {
      "type": "object",
      "properties": {
        "apikey": {
          "type": "string"
        }
      }
    }
  },
  "anyOf": [
    {"required": ["headers"["api_key"]]}, // what should this be??
    {"required": ["query_string"["apikey"]]} // what should this be??
  ]
}

我认为是 anyOf 我正在寻找,但我不知道如何引用上面的嵌套 json 项。

此时我得到一个错误:

JSON syntax is malformed

我正在使用 Justin Rainbow,因为我正在为此使用 PHP。

有几种方法。最直接的是:

{
  "title": "Application Get Single",
  "type": "object",
  "properties": {
    "headers": {
      "type": "object",
      "properties": {
        "api_key": {
          "type": "string"
        }
      }
    },
    "query_string": {
      "type": "object",
      "properties": {
        "apikey": {
          "type": "string"
        }
      }
    }
  },
  "anyOf": [
    {
      "properties": {
        "headers": {
            "type": "object",
            "required":["api_key"]
        }
      }
    },
    {
      "properties": {
        "query_string": {
            "type": "object",
            "required":["apikey"]
        }
      }
    }
  ]
}

您可能还希望在根 object 上使用 "minProperties": 1,以确保 headers 或 query_string 存在。

编辑:只是 re-read 问题,如果 headers.api_key 和 query_string.apikey 互斥,则将 anyOf 更改为 oneOf

诀窍是 "and not the other" 部分。这是我的建议(假设是 draft-06 或更高版本,请参阅下面的 draft-04):

{
  "title": "Application Get Single",
  "type": "object",
  "properties": {
    "headers": {
      "type": "object",
      "properties": {
        "api_key": {
          "type": "string"
        }
      }
    },
    "query_string": {
      "type": "object",
      "properties": {
        "apikey": {
          "type": "string"
        }
      }
    }
  },
  "oneOf": [
    {
      "required": ["headers"],
      "query_string": false
    },
    {
      "required": ["query_string"],
      "headers": false
    }
  ]
}

对于 draft-04,将 false 替换为 {"not": {}},意思相同但读起来很烦人。但是你不能在 draft-04 的大多数地方使用布尔模式,所以你需要用冗长的方式说 "this property must not be present".