有条件地将 additionalProperties 应用于子对象,但不应用于引用它的父对象

Conditionally apply additionalProperties on child but not on parent that references it

我希望实现两个模式,其中一个是另一个的数组,我们称这个为 Payload B,另一个为 Payload A。

问题:父架构需要一个附加键,而子架构不允许。

有效负载A:

{
  "a": "a",
  "b": "b",
  "c": "2019-05-01T09:00:00Z"
}

使用以下模式实施:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "item-schema.json",
  "title": "Individual Item POST",
  "description": "",
  "type": "object",
  "properties": {
    "a": {
      "type": "string"
    },
    "b": {
      "type": "string"
    },
    "c": {
      "type": "string",
      "format": "date-time"
    }
  },
  "additionalProperties": false,
  "required": [
    "a",
    "b",
    "c"
  ]
}

有效负载 B:

[
  {
    "a": "aa",
    "b": "bb",
    "c": "2019-05-01T10:00:00Z",
    "d": "dd"
  },
  {
    "a": "aaa",
    "b": "bbb",
    "c": "2019-05-01T11:00:00Z",
    "d": "ddd"
  }
]

使用以下模式实施:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "items-schema.json",
  "title": "Multiple Item POST",
  "description": "",
  "type": "array",
  "items": {
    "allOf": [
      {
        "$ref": "item-schema.json"
      },
      {
        "properties": {
          "d": {
            "type": "string"
          }
        }
      }
    ]
  },
  "additionalItems": false
}

我遇到的问题是,虽然有效载荷 A 得到了正确验证,因为它不允许任何无关的密钥,但由于有效载荷 A 的架构,有效载荷 B 无效。

使用 draft-7 JSON 模式实现您想要的唯一方法是在您的模式中复制。

您需要将 allOf/1 修改为 properties:a,b,c:true(记住,布尔值是模式)并添加 additionalProperties:false.

并且您必须从项目-schema.json 中删除 additionalProperties:false

如果您不能这样做并且您需要 item-schema.json 单独工作,那么我很抱歉:您运气不好,所以您必须复制架构而不是引用它。

认识到这不是很好,我们努力工作(我批准了 PR。支持核心团队的其他成员!)为 draft-8 unevaluatedProperties 创建一个新关键字。您可以在 https://github.com/json-schema-org/json-schema-spec/issues/556.

阅读相关信息

如果有什么安慰的话,OpenAPI 规范也有同样的问题,这在上面引用的问题中有解释。