条件 属性 类型
Conditional property type
我如何创建一个 JSON 模式,它具有基于另一个 属性 的值的条件 属性 类型。
我有这个:
{ // Header info removed for brevity
"definitions": {
"payloadTypeA": {
"type": "object",
"properties": {
"requestType": {"type": "string","enum": ["A1", "A2"]}},
},
"payloadTypeB": {
"type": "object",
"properties": {
"requestType": {"type": "string","enum": ["B1","B2"]}}
}
},
"type": "object",
"properties": {
"workload": {
"type": "string",
"enum": ["A","B"]
},
"payload": {
"oneOf": [
{
"if": {"properties": {"workload": {"const": "A"}}},
"then": {"$ref": "#/definitions/payloadTypeA"}},
{
"if": {"properties": {"workload": {"const": "B"}}},
"then": {"$ref": "#/definitions/payloadTypeB"}}
]
}
}
}
我希望它在 workload
的值为 "A" 时使用 PayloadTypeA,在 workload
为 "B" 时使用 PayloadTypeB。但是,这验证了:
{
"workload": "B",
"payload": {
"requestType": "A1",
}
}
这也验证了:
{
"workload": "B",
"payload": {
"requestType": "B1",
}
}
但这不是:
{
"workload": "B",
"payload": {
"requestType": "C1",
}
}
因此,无论工作负载的值如何,它似乎都在针对任一有效负载模式进行验证。
我有工作负载值的其他条件,所以我不能只使用普通的 if/then/else
,因为我有一个很大的 if/then/else
嵌套结构,维护起来会是一场噩梦。
你有几个问题。让我们从部分架构的简化版本开始。
"properties": {
"workload": { "enum": ["A","B"] },
"payload": {
"if": { "properties": { "workload": { "const": "A" } } },
"then": { "$ref": "#/definitions/payloadTypeA" }
}
}
当您在此处放置 if
架构时,"workload" 属性 应位于 "payload" 属性 之下,而不是顶层。如果您正在验证一个看起来像这样的结构,这将起作用。
{
"payload": {
"workload": "B",
"requestType": "B1",
}
}
要让它工作,您必须将 if
/then
块拉到更高级别的模式,它可以访问 "workload" 属性.
"properties": {
"workload": { "enum": ["A","B"] }
},
"if": { "properties": { "workload": { "const": "A" } } },
"then": { "properties": { "payload": { "$ref": "#/definitions/payloadTypeA" } } }
下一个问题是如何组合条件。将上述修复与您现在拥有的相结合,它看起来像这样。
"properties": {
"workload": { "enum": ["A","B"] }
},
"oneOf": [
{
"if": { "properties": { "workload": { "const": "A" } } },
"then": { "properties": { "payload": { "$ref": "#/definitions/payloadTypeA" } } }
},
{
"if": { "properties": { "workload": { "const": "B" } } },
"then": { "properties": { "payload": { "$ref": "#/definitions/payloadTypeB" } } }
}
]
当 if
失败时,它不会使架构失败。仅当 if
通过 且 then
为假时,架构才会失败。所以,如果给定一个像这样的有效模式。
{
"workload": "B",
"payload": {
"requestType": "B1",
}
}
/oneOf/0
将通过,因为 /oneOf/0/if
失败。
/oneOf/1
将通过,因为 /oneOf/1/if
通过并且 /oneOf/1/then
通过。
由于两个模式都通过了,oneOf
失败了。您可以从此示例推断,只有当所有条件都通过时,模式才应该通过。只需将 oneOf
替换为 allOf
即可。
"properties": {
"workload": { "enum": ["A","B"] }
},
"allOf": [
{
"if": { "properties": { "workload": { "const": "A" } } },
"then": { "properties": { "payload": { "$ref": "#/definitions/payloadTypeA" } } }
},
{
"if": { "properties": { "workload": { "const": "B" } } },
"then": { "properties": { "payload": { "$ref": "#/definitions/payloadTypeB" } } }
}
]
我如何创建一个 JSON 模式,它具有基于另一个 属性 的值的条件 属性 类型。
我有这个:
{ // Header info removed for brevity
"definitions": {
"payloadTypeA": {
"type": "object",
"properties": {
"requestType": {"type": "string","enum": ["A1", "A2"]}},
},
"payloadTypeB": {
"type": "object",
"properties": {
"requestType": {"type": "string","enum": ["B1","B2"]}}
}
},
"type": "object",
"properties": {
"workload": {
"type": "string",
"enum": ["A","B"]
},
"payload": {
"oneOf": [
{
"if": {"properties": {"workload": {"const": "A"}}},
"then": {"$ref": "#/definitions/payloadTypeA"}},
{
"if": {"properties": {"workload": {"const": "B"}}},
"then": {"$ref": "#/definitions/payloadTypeB"}}
]
}
}
}
我希望它在 workload
的值为 "A" 时使用 PayloadTypeA,在 workload
为 "B" 时使用 PayloadTypeB。但是,这验证了:
{
"workload": "B",
"payload": {
"requestType": "A1",
}
}
这也验证了:
{
"workload": "B",
"payload": {
"requestType": "B1",
}
}
但这不是:
{
"workload": "B",
"payload": {
"requestType": "C1",
}
}
因此,无论工作负载的值如何,它似乎都在针对任一有效负载模式进行验证。
我有工作负载值的其他条件,所以我不能只使用普通的 if/then/else
,因为我有一个很大的 if/then/else
嵌套结构,维护起来会是一场噩梦。
你有几个问题。让我们从部分架构的简化版本开始。
"properties": {
"workload": { "enum": ["A","B"] },
"payload": {
"if": { "properties": { "workload": { "const": "A" } } },
"then": { "$ref": "#/definitions/payloadTypeA" }
}
}
当您在此处放置 if
架构时,"workload" 属性 应位于 "payload" 属性 之下,而不是顶层。如果您正在验证一个看起来像这样的结构,这将起作用。
{
"payload": {
"workload": "B",
"requestType": "B1",
}
}
要让它工作,您必须将 if
/then
块拉到更高级别的模式,它可以访问 "workload" 属性.
"properties": {
"workload": { "enum": ["A","B"] }
},
"if": { "properties": { "workload": { "const": "A" } } },
"then": { "properties": { "payload": { "$ref": "#/definitions/payloadTypeA" } } }
下一个问题是如何组合条件。将上述修复与您现在拥有的相结合,它看起来像这样。
"properties": {
"workload": { "enum": ["A","B"] }
},
"oneOf": [
{
"if": { "properties": { "workload": { "const": "A" } } },
"then": { "properties": { "payload": { "$ref": "#/definitions/payloadTypeA" } } }
},
{
"if": { "properties": { "workload": { "const": "B" } } },
"then": { "properties": { "payload": { "$ref": "#/definitions/payloadTypeB" } } }
}
]
当 if
失败时,它不会使架构失败。仅当 if
通过 且 then
为假时,架构才会失败。所以,如果给定一个像这样的有效模式。
{
"workload": "B",
"payload": {
"requestType": "B1",
}
}
/oneOf/0
将通过,因为/oneOf/0/if
失败。/oneOf/1
将通过,因为/oneOf/1/if
通过并且/oneOf/1/then
通过。
由于两个模式都通过了,oneOf
失败了。您可以从此示例推断,只有当所有条件都通过时,模式才应该通过。只需将 oneOf
替换为 allOf
即可。
"properties": {
"workload": { "enum": ["A","B"] }
},
"allOf": [
{
"if": { "properties": { "workload": { "const": "A" } } },
"then": { "properties": { "payload": { "$ref": "#/definitions/payloadTypeA" } } }
},
{
"if": { "properties": { "workload": { "const": "B" } } },
"then": { "properties": { "payload": { "$ref": "#/definitions/payloadTypeB" } } }
}
]