什么相当于 OpenAPI 3.1 中的多种类型? anyOf 还是 oneOf?
What is equivalent to multiple types in OpenAPI 3.1? anyOf or oneOf?
我想将多种类型(在 JSON 架构的最新草案中支持,OpenAPI v3.1 也支持)更改为 anyOf
、oneOf
,但我有点困惑类型将映射到哪个。或者我可以映射到两者中的任何一个。
PS。我确实了解 anyOf
、oneOf
等,但多类型行为有点模棱两可。 (我知道模式无效,但这只是一个更侧重于类型转换的示例)
{
"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"
}
]
}
anyOf
比 oneOf
;
更接近语义匹配
oneOf
的问题(或好处!)是,如果您碰巧匹配 2 个不同的案例,它将失败。
这不太可能是您想要的,因为您的转换源具有那些更宽松的语义。
想象一下转换 ["integer","number"]
,例如;如果输入是 1
,您将同时匹配两者并使用 oneOf
.
失败
首先,你的例子是无效的:
初始架构不匹配任何内容,这是一个“不可能”的架构。 "enum": [2, 3, 4, 5]
和 "const": "sample const entry"
约束是互斥的,"const": "sample const entry"
和 "maxLength": 10
也是如此。
重写的架构不等同于原始架构,因为 enum
和 const
已从根级别移动到子架构中。是的,这种模式更有意义并且会有点工作(例如,它将匹配指定的数字 - 但不是字符串!因为 const
与 maxLength
矛盾),但它与原来的不一样架构。
关于oneOf
/anyOf
:
视情况而定。
anyOf
和oneOf
之间的选择取决于上下文,即实例是否可以匹配多个子模式或正好一个 子模式。换句话说,多个子模式匹配是否被认为是 OK 或错误。 通常需要 anyOf
而不是 oneOf
,但其他情况因架构而异。
例如,
"type": ["number", "integer"]
对应于 anyOf
因为存在重叠 - 整数值在 JSON 架构中也是有效的“数字”值。
鉴于
"type": ["string", "integer"]
可以用 oneOf
或 anyOf
表示。 oneOf
在语义上更接近,因为字符串和整数是完全不同的数据类型,没有重叠。但技术上 anyOf
也有效,只是在这种特殊情况下不会有超过一个子模式匹配。
在您的示例中,所有基础 type
值都是不同的,没有重叠,所以我会使用 oneOf
,但技术上 anyOf
也可以。
我想将多种类型(在 JSON 架构的最新草案中支持,OpenAPI v3.1 也支持)更改为 anyOf
、oneOf
,但我有点困惑类型将映射到哪个。或者我可以映射到两者中的任何一个。
PS。我确实了解 anyOf
、oneOf
等,但多类型行为有点模棱两可。 (我知道模式无效,但这只是一个更侧重于类型转换的示例)
{
"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"
}
]
}
anyOf
比 oneOf
;
oneOf
的问题(或好处!)是,如果您碰巧匹配 2 个不同的案例,它将失败。
这不太可能是您想要的,因为您的转换源具有那些更宽松的语义。
想象一下转换 ["integer","number"]
,例如;如果输入是 1
,您将同时匹配两者并使用 oneOf
.
首先,你的例子是无效的:
初始架构不匹配任何内容,这是一个“不可能”的架构。
"enum": [2, 3, 4, 5]
和"const": "sample const entry"
约束是互斥的,"const": "sample const entry"
和"maxLength": 10
也是如此。重写的架构不等同于原始架构,因为
enum
和const
已从根级别移动到子架构中。是的,这种模式更有意义并且会有点工作(例如,它将匹配指定的数字 - 但不是字符串!因为const
与maxLength
矛盾),但它与原来的不一样架构。
关于oneOf
/anyOf
:
视情况而定。
anyOf
和oneOf
之间的选择取决于上下文,即实例是否可以匹配多个子模式或正好一个 子模式。换句话说,多个子模式匹配是否被认为是 OK 或错误。 anyOf
而不是 oneOf
,但其他情况因架构而异。
例如,
"type": ["number", "integer"]
对应于 anyOf
因为存在重叠 - 整数值在 JSON 架构中也是有效的“数字”值。
鉴于
"type": ["string", "integer"]
可以用 oneOf
或 anyOf
表示。 oneOf
在语义上更接近,因为字符串和整数是完全不同的数据类型,没有重叠。但技术上 anyOf
也有效,只是在这种特殊情况下不会有超过一个子模式匹配。
在您的示例中,所有基础 type
值都是不同的,没有重叠,所以我会使用 oneOf
,但技术上 anyOf
也可以。