【发布时间】:2018-04-13 18:53:31
【问题描述】:
我需要根据 JSON 模式 (draft-04) 验证许多对象(消息)。每个对象都保证有一个“类型”字段,用于描述其类型,但每种类型都有一组完全不同的其他字段,因此每种类型的对象都需要一个唯一的模式。
我看到了几种可能性,但没有一个特别吸引人,但我希望我遗漏了一些东西。
可能性 1:对每种消息类型使用 oneOf。我想这会起作用,但问题是很长的验证错误,以防出现问题:验证器倾向于报告每个失败的模式,其中包括“oneOf”数组中的所有元素。
{
"oneOf":
[
{
"type": "object",
"properties":
{
"t":
{
"type": "string",
"enum":
[
"message_type_1"
]
}
}
},
{
"type": "object",
"properties":
{
"t":
{
"type": "string",
"enum":
[
"message_type_2"
]
},
"some_other_property":
{
"type": "integer"
}
},
"required":
[
"some_other_property"
]
}
]
}
可能性2:嵌套“if”、“then”、“else”三元组。我没有尝试过,但我想在这种情况下错误可能会更好。但是写起来很麻烦,因为嵌套if的堆积。
可能性 3:为“t”的每个可能值提供单独的方案。这是最简单的解决方案,但我不喜欢它,因为它使我无法在架构中使用公共元素(通过引用)。
那么,这些是我唯一的选择,还是我可以做得更好?
【问题讨论】:
-
选项 3 并不妨碍您使用参考。引用另一个模式文件的一部分是完全有效和可能的。并不是说这是最好的选择。
-
我认为选项 1 是您最好的选择。如果验证器不满足数组中的任何模式,则验证器有权报告来自
oneOf的所有错误。您是否希望能够将任何错误消息发回给用户以获取验证反馈? -
我希望用户——实际上是开发人员或测试人员——能够快速查明问题。至少会有几十种消息类型,并且得到一个列出所有这些类型的巨大错误并不完全有助于实现该目标。我越来越多地考虑选项3。你说得对,我仍然可以使用 refs,但我必须为每个消息模式加载包含该 ref 的文件。不理想,但可能必须这样做。
-
同意。是的,如果库不支持文件 URI 协议(有些支持,但未定义行为),则必须将它们加载到库中。当您需要进行验证时,执行多个 HTTP 请求不太理想!
标签: jsonschema