JSON模式中的条件引用



我想编写一个带有多个子模式的单文件JSON模式定义,这些子模式可以根据负载组合。

下面的模式验证了我的模式正在使用我的示例JSON响应。(响应对象的payload.role类型错误,以确保架构捕捉到此错误!(

为了清楚起见,我在最重要的部分减少了它。完整的工作示例可在此处找到:https://www.jsonschemavalidator.net/s/3KAaXjtg

架构

{
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "http://example.com/baseSchema.json",
"type": "object",
"required": [
"payload"
],
"properties": {
"payload": {
"$id": "#/properties/payload",
"type": "object",
// reference the right schema depending on the payload child key
// if `payload.user` reference `userSchema.json`
// if `payload.users` reference `usersSchema.json`
// if `payload.*` reference `*Schema.json`
"$ref": "userSchema.json"
}
},
"definitions": {
"user": {
"$id": "http://example.com/userSchema.json",
"type": "object",
"required": [
"user"
],
"properties": {
"user": {
"type": "object",
"$ref": "userProperties.json"
}
}
},
"users": {
"$id": "http://example.com/usersSchema.json",
"type": "object",
"required": [
"users"
],
"properties": {
"users": {
"type": "array",
"items": {
"$ref": "userProperties.json"
}
}
}
},
"userProperties": {
"$id": "http://example.com/userProperties.json",
"type": "object",
"properties": {
"firstName": {
"$id": "#/properties/payload/properties/user/properties/firstName",
"type": "string"
}
}
}
}
}

响应

{
"status": {
"code": 200,
"description": "User retrieved successfully."
},
"payload": {
"user": {
"firstName": "Joe",
"lastName": "Doe",
"role": "3", // for testing reasons, this is the wrong type!
"email": "doe@example.com",
"customerID": "",
"projects": [
"AIXG5mEg6QLl9rhVSE6m",
"Bs1bHiOIqKclwwis3CNf",
"NC2OUGVZXU35FA7iwRn4"
],
"status": "Status",
"id": "c555BSZnKLdHSRYqrU5hqiQo733j13"
}
}
}

因此,我得到了一个与此响应匹配的baseSchema.json

{
"status": {},
"payload": {}
}

payload由某个键(如payload.user = {}payload.foo = {}(扩展,根据该键,我想用我的一个定义来扩展模式。

以下部分仅适用于密钥user:

"properties": {
"payload": {
"$id": "#/properties/payload",
"type": "object",
// reference the right schema depending on the payload child key
// if `payload.user` reference `userSchema.json`
// if `payload.users` reference `usersSchema.json`
// if `payload.*` reference `*Schema.json`
"$ref": "userSchema.json"
}
},

我无法设置任何条件(使用allOfifelse(,这些条件将基于payload键引用正确的子模式。

如有任何提示和帮助,我们将不胜感激。

架构和最后的演示链接。。。让我们看看我们是如何到达那里的。。。

在JSONSchema draft-07和以前的版本中,不能将$ref与其他关键字一起使用。其他关键字将被忽略。(在您的模式http://example.com/userSchema.json中,type位于$ref旁边(。幸运的是,当您在引用的模式中声明类型时,这并没有给您带来任何问题。(您可以在2019-09或更高版本中做到这一点。(

关键字ifthenelse的值是模式。对于要应用于实例位置的then子模式,if模式必须返回为有效模式。如果失败,将应用else子模式值。

我们的if条件检查是否存在特定密钥。如果密钥存在,则应用引用正确模式的模式。

因为希望条件互斥,所以需要将多个条件包装在oneOf中,并将else: false添加到条件检查中。false作为模式会导致验证失败。

如果你想进一步澄清以上任何一点,请告诉我。

演示:https://jsonschema.dev/s/HLniL

{
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "http://example.com/baseSchema.json",
"type": "object",
"required": [
"payload"
],
"properties": {
"payload": {
"$id": "#/properties/payload",
"type": "object",
"oneOf": [
{
"if": {
"required": [
"user"
]
},
"then": {
"$ref": "userSchema.json"
},
"else": false
},
{
"if": {
"required": [
"users"
]
},
"then": {
"$ref": "usersSchema.json"
},
"else": false
}
]
}
},
"definitions": {
"user": {
"$id": "http://example.com/userSchema.json",
"type": "object",
"required": [
"user"
],
"properties": {
"user": {
"$ref": "userProperties.json"
}
}
},
"users": {
"$id": "http://example.com/usersSchema.json",
"type": "object",
"required": [
"users"
],
"properties": {
"users": {
"type": "array",
"items": {
"$ref": "userProperties.json"
}
}
}
},
"userProperties": {
"$id": "http://example.com/userProperties.json",
"type": "object",
"properties": {
"firstName": {
"type": "string"
}
}
}
}
}

相关内容

  • 没有找到相关文章

最新更新