JsonSchema 可以接受遗留和扩展的有效负载

问题描述 投票:0回答:1

我正在扩展现有功能,因此 API 负载需要更新。由于我无法控制的限制,我需要同时支持旧有效负载和新有效负载。此验证还需要根据新策略重新实现为 JsonSchema。

旧的有效负载是一成不变的,新的有效负载可能会进行一些调整,但我更愿意保持原样。

旧有效负载是:

{
  "OPTION": {
    "property1": "someString",
    "property2": <integer>
  }
}

新的有效负载将添加额外的属性以及创建多个对象的能力,例如:

{
  "OPTION": {
    "object1": {
      "property1": "someString",
      "property2": <integer>,
      "property3": <boolean>
    },
    ...
    "objectN": {
      "property1": "someString",
      "property2": <integer>,
      "property3": <boolean>
    }
  }
}

我最初的尝试没有成功。这是一个对我来说直觉上似乎正确的尝试。错误:[“属性‘property1’尚未定义,架构不允许附加属性。”、“属性‘property2’尚未定义,架构不允许附加属性。”

{
"$schema": "http://json-schema.org/draft/2020-12/schema",
"title": "Title",
"description": "Version...",
"type": "object",
"patternProperties": {
    "^[A-Z0-9]*$": {
        "type": "object",
        "title": "sub-title",
        "description": "...",
        "examples": [
            "OPTION"
        ],
        "oneOf": [
            {
                "type": "object",
                "properties": {
                    "property1": {
                        "type": "string"
                    },
                    "property2": {
                        "type": "integer"
                    }
                }
            },
            {
                "type": "array",
                "items": {
                    "type": "object",
                    "properties": {
                        "property1": {
                            "type": "string"
                        },
                        "property2": {
                            "type": "integer"
                        },
                        "property3": {
                            "type": "boolean"
                        },
                        "additionalProperties": false
                    }
                }
            }
        ],
        "additionalProperties": false
    }
    }
}

编辑:修复了错误的复制/粘贴

jsonschema json-schema-validator
1个回答
0
投票

这是您想要使用

unevaluatedProperties
而不是
additionalProperties
的时候。

additionalProperties
只能看到直接模式对象中定义的属性。 它无法看到由直接模式对象的子模式定义的属性。

{
  "properties": {
    "foo": true              // seen
  },
  "patternProperties": {
    "^[a-z]+[0-9]+$": true   // seen (property requires letters AND numbers)
  },
  "allOf": [
    {
      "properties": {
        "bar": false         // not seen
      }
    }
  ],
  "additionalProperties": false
}

但是,

unevaluatedProperties
可以看到这些子模式的内部,因此对于上面的内容,如果您使用
bar
代替,则可以看到
unevaluatedProperties


您可能还想检查新设计的子模式。 子模式当前描述了

OPTIONS
值的数组,但新数据的示例是具有“optionN”属性的对象。


最后,一点重构可以通过隔离每种可能的形式来帮助提高可读性。 通过使用

$ref
$defs
,您可以创建支持每种表单的标记子模式。

{
  "$schema": "http://json-schema.org/draft/2020-12/schema",
  "title": "Title",
  "description": "Version...",
  "type": "object",
  "patternProperties": {
    "^[A-Z0-9]*$": {
      "type": "object",
      "title": "sub-title",
      "description": "...",
      "examples": [
        "OPTION"
      ],
      "oneOf": [
        { "$ref": "#/$defs/legacy" },
        { "$ref": "#/$defs/theNewWay" }
      ],
      "unevaluatedProperties": false
    }
  },
  "$defs": {
    "legacy": {
      "type": "object",
      "properties": {
        "property1": {
          "type": "string"
        },
        "property2": {
          "type": "integer"
        }
      }
    },
    "theNewWay": {                // obviously rename this :)
      "type": "array",            // (and review this schema, maybe)
      "items": {
        "type": "object",
        "properties": {
          "property1": {
            "type": "string"
          },
          "property2": {
            "type": "integer"
          },
          "property3": {
            "type": "boolean"
          },
          "additionalProperties": false
        }
      }
    }
  }
}
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.