JSON 模式中的条件引用
Conditional References in a JSON Schema
我想编写一个文件 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"
}
},
我未能设置任何 conditions(使用 allOf
、if
、else
),它会根据 payload
键。
感谢任何提示和帮助解决这个问题。
Schema 和 link 最后演示...让我们看看我们是如何到达那里的...
在 JSON Schema draft-07 及之前的版本中,您不能将 $ref
与其他关键字一起使用。其他关键字将被忽略。 (在您的架构 http://example.com/userSchema.json
中,$ref
旁边有 type
。幸运的是,当您在引用模式中声明类型时,这并没有给您带来任何问题。 (您可以使用 2019-09 或更高版本执行此操作。)
关键字 if
、then
和 else
的值是架构。
要将 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"
}
}
}
}
}
我想编写一个文件 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"
}
},
我未能设置任何 conditions(使用 allOf
、if
、else
),它会根据 payload
键。
感谢任何提示和帮助解决这个问题。
Schema 和 link 最后演示...让我们看看我们是如何到达那里的...
在 JSON Schema draft-07 及之前的版本中,您不能将 $ref
与其他关键字一起使用。其他关键字将被忽略。 (在您的架构 http://example.com/userSchema.json
中,$ref
旁边有 type
。幸运的是,当您在引用模式中声明类型时,这并没有给您带来任何问题。 (您可以使用 2019-09 或更高版本执行此操作。)
关键字 if
、then
和 else
的值是架构。
要将 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"
}
}
}
}
}