Jsonschema 如何在单个JSON模式上验证输入和输出(具有只读的边缘案例)
我的问题有些重叠,但差异很大,我觉得有必要提出一个新问题 我试图理解设计一个模式的最佳方法,该模式可用于在单个资源表示上验证输入和输出。这里有一个例子Jsonschema 如何在单个JSON模式上验证输入和输出(具有只读的边缘案例),jsonschema,Jsonschema,我的问题有些重叠,但差异很大,我觉得有必要提出一个新问题 我试图理解设计一个模式的最佳方法,该模式可用于在单个资源表示上验证输入和输出。这里有一个例子 { "type": "object", "properties": { "id": { "type": "number", "readOnly": true }, "title": { "type": "stri
{
"type": "object",
"properties": {
"id": {
"type": "number",
"readOnly": true
},
"title": {
"type": "string"
},
"post": {
"type": "string"
}
},
"required": ["id", "title", "post"],
"additionalProperties": false
};
问题是,在验证输出时,我们需要id
、title
和post
必需。验证输入时,不需要一个或多个字段,如果它们提供id
,我希望验证失败(由于只读
关键字)
我认为正确的方法是将required
与or结合起来,但我不确定如何将它们结合在一起
这是正确的道路,还是有更好的解决方案?有没有人有一个使用最新版本的JSON模式的例子(现在是草案7)
谢谢 这里有几种可能的方法 首先,
readOnly
不会导致JSON模式的验证过程失败。它不是一个断言,只是一个注释,应用程序可以使用它来执行操作。因此,您的服务器应用程序可以按照自己的意愿处理该问题—如果有人试图更改它,则会引发错误,或者只是默默地忽略新值
或者查看HTTPpreference
标题,如果存在handling=lenient
,则忽略任何更改只读值的尝试,但如果存在handling=strict
,则任何尝试都会出错
或者以不同的方式处理不同的字段。如果您有一个lastModified
字段并支持HTTP GET=>modify=>HTTP PUT工作流,那么当您放回一个表示时,lastModified
将不可避免地出错,但在某一点上是只读的。您不希望为过期的自动生成的时间戳中断PUT。但是,如果有人认为他们可以更改id
字段,您可能确实希望引发错误
有鉴于此,有两种通用方法:编写一个双向工作的模式,并在应用程序层中执行额外的检查,或者分别确定输入和输出的所有内容
“双向工作”方法将从必需的中删除id
,但文档一旦创建,资源将始终具有id
。但这样一来,在创建或编写时就可以省略它,而不会出现问题。要确定这是否合理,请考虑客户端输出验证的用例。客户机是否真的需要JSON模式来检查服务器是否发送了id
,或者客户机是否可以根据文档合理地假设服务器将正确执行此操作
对于“锁定每一个方向”的方法,您可以这样做:
{
"definitions": {
"common": {
"type": "object",
"properties": {
"id": {
"type": "number",
"readOnly": true
},
"title": {
"type": "string"
},
"post": {
"type": "string"
}
},
"required": ["title", "post"],
"additionalProperties": false
},
"input": {
"allOf": [
{"$ref": "#/definitions/common"},
{"properties": {"id": false}}
]
},
"output": {
"allOf": [
{"$ref": "#/definitions/common"},
{"required": ["id"]}
]
}
}
}
您需要在公共模式中定义id
,以便“additionalProperties”:false
了解它(我尽量避免“additionalProperties”:false
,因为它使以兼容的方式演化表示变得困难,但如果您想使用它,这就是如何使它工作的方法)
对于输出,只需设置id
required即可
对于输入,使用{“属性”:{“id”:false}
禁止id
。即使它是在“common”中定义的,false
布尔模式总是会导致id
在输入时验证失败
当然,您必须弄清楚应用程序如何知道要使用哪个模式,因为readOnly
本身不会导致验证失败。这就是为什么我更喜欢读写都有一个模式,让应用程序处理差异(并记录这种处理是如何工作的)