什么相当于 OpenAPI 3.1 中的多种类型? anyOf 还是 oneOf?

What is equivalent to multiple types in OpenAPI 3.1? anyOf or oneOf?

我想将多种类型(在 JSON 架构的最新草案中支持,OpenAPI v3.1 也支持)更改为 anyOfoneOf,但我有点困惑类型将映射到哪个。或者我可以映射到两者中的任何一个。

PS。我确实了解 anyOfoneOf 等,但多类型行为有点模棱两可。 (我知道模式无效,但这只是一个更侧重于类型转换的示例)

{
    "type": ["null", "object", "integer", "string"],
    "properties": {
        "prop1": {
            "type": "string"
        },
        "prop2": {
            "type": "string"
        }
    },
    "enum": [2, 3, 4, 5],
    "const": "sample const entry",
    "exclusiveMinimum": 1.22,
    "exclusiveMaximum": 50,
    "maxLength": 10,
    "minLength": 2,
    "format": "int32"
}

我正在这样转换。

{
    "anyOf": [{
            "type": "null"
        },
        {
            "type": "object",
            "properties": {
                "prop1": {
                    "type": "string"
                },
                "prop2": {
                    "type": "string"
                }
            }
        },
        {
            "type": "integer",
            "enum": [2, 3, 4, 5],
            "exclusiveMinimum": 1.22,
            "exclusiveMaximum": 50,
            "format": "int32"
        },
        {
            "type": "string",
            "maxLength": 10,
            "minLength": 2,
            "const": "sample const entry"
        }
    ]
}

anyOfoneOf;

更接近语义匹配

oneOf 的问题(或好处!)是,如果您碰巧匹配 2 个不同的案例,它将失败。

这不太可能是您想要的,因为您的转换源具有那些更宽松的语义。

想象一下转换 ["integer","number"],例如;如果输入是 1,您将同时匹配两者并使用 oneOf.

失败

首先,你的例子是无效的:

  1. 初始架构不匹配任何内容,这是一个“不可能”的架构。 "enum": [2, 3, 4, 5]"const": "sample const entry" 约束是互斥的,"const": "sample const entry""maxLength": 10 也是如此。

  2. 重写的架构不等同于原始架构,因为 enumconst 已从根级别移动到子架构中。是的,这种模式更有意义并且会有点工作(例如,它将匹配指定的数字 - 但不是字符串!因为 constmaxLength 矛盾),但它与原来的不一样架构。


关于oneOf/anyOf:

视情况而定。

anyOfoneOf之间的选择取决于上下文,即实例是否可以匹配多个子模式或正好一个 子模式。换句话说,多个子模式匹配是否被认为是 OK 或错误。 通常需要 anyOf 而不是 oneOf,但其他情况因架构而异。

例如,

"type": ["number", "integer"]

对应于 anyOf 因为存在重叠 - 整数值在 JSON 架构中也是有效的“数字”值。

鉴于

"type": ["string", "integer"]

可以用 oneOfanyOf 表示。 oneOf 在语义上更接近,因为字符串和整数是完全不同的数据类型,没有重叠。但技术上 anyOf 也有效,只是在这种特殊情况下不会有超过一个子模式匹配。


在您的示例中,所有基础 type 值都是不同的,没有重叠,所以我会使用 oneOf,但技术上 anyOf 也可以。