JSON 架构:为什么 "constant" 的验证方式与单值 "enum" 不同?
JSON schema: Why does "constant" not validate the same way as a single-valued "enum"?
我有一个对象,它提供一种资产版本的审计日志。它的几个属性(versionSource.metadata
和 versionSource.files
)是应该根据其中一个属性的值根据两个模式之一进行验证的对象。我开始在我的子模式中使用常量(在 oneOf
内,但那是说所有子模式都经过验证(因此打破了 oneOf
,因为不止一个经过验证。将其更改为不过,单值枚举有效。
为什么验证不同?
这是原始架构:
{
"$id": "https://example.com/schemas/asset-version.json",
"title": "Audit log of asset versions",
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"required": [
"assetID",
"version",
"versionSource"
],
"properties": {
"assetID": {
"type": "string"
},
"version": {
"type": "integer",
"minimum": 1
},
"versionSource": {
"type": "object",
"properties": {
"metadata": {
"type": "object",
"oneOf": [
{
"properties": {
"sourceType": { "constant": "client" }
}
},
{
"$ref": "#/definitions/version-source-previous-version"
}
]
},
"files": {
"type": "object",
"oneOf": [
{
"properties": {
"sourceType": { "constant": "upload" },
"sourceID": {
"type": "string"
}
}
},
{
"$ref": "#/definitions/version-source-previous-version"
}
]
}
}
}
},
"definitions": {
"version-source-previous-version": {
"properties": {
"sourceType": { "constant": "previous-version" },
"sourceID": {
"type": "integer",
"minimum": 1
}
}
}
}
}
这是一份示例文档:
{
"assetID": "0150a186-068d-43e7-bb8b-0a389b572379",
"version": 1,
"versionSource": {
"metadata": {
"sourceType": "client"
},
"files": {
"sourceType": "upload",
"sourceID": "54ae67b0-3e42-464a-a93f-3143b0f078fc"
}
},
"created": "2018-09-01T00:00:00.00Z",
"lastModified": "2018-09-02T12:10:00.00Z",
"deleted": "2018-09-02T12:10:00.00Z"
}
还有一个:
{
"assetID": "0150a186-068d-43e7-bb8b-0a389b572379",
"version": 2,
"versionSource": {
"metadata": {
"sourceType": "previous-version",
"sourceID": 1
},
"files": {
"sourceType": "previous-version",
"sourceID": 1
}
},
"created": "2018-09-01T00:00:00.00Z",
"lastModified": "2018-09-02T12:10:00.00Z",
"deleted": "2018-09-02T12:10:00.00Z"
}
这是我得到的错误:
消息:JSON 对来自 'oneOf' 的多个模式有效。有效的架构索引:0、1。
架构路径:
https://example.com/schemas/asset-version.json#/properties/versionSource/properties/metadata/oneOf
由于 sourceType
在 oneOf
的两个模式中都是常量,我真的不确定我的对象如何对这两个模式有效。
不过,将架构更改为以下内容有效:
{
"$id": "https://example.com/schemas/asset-version.json",
"title": "Audit log of asset versions",
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"required": [
"assetID",
"version",
"versionSource"
],
"properties": {
"assetID": {
"type": "string"
},
"version": {
"type": "integer",
"minimum": 1
},
"versionSource": {
"type": "object",
"properties": {
"metadata": {
"type": "object",
"oneOf": [
{
"properties": {
"sourceType": { "enum": [ "client" ] }
}
},
{
"$ref": "#/definitions/version-source-previous-version"
}
]
},
"files": {
"type": "object",
"oneOf": [
{
"properties": {
"sourceType": { "enum": [ "upload" ] },
"sourceID": {
"type": "string"
}
}
},
{
"$ref": "#/definitions/version-source-previous-version"
}
]
}
}
}
},
"definitions": {
"version-source-previous-version": {
"properties": {
"sourceType": { "enum": [ "previous-version" ] },
"sourceID": {
"type": "integer",
"minimum": 1
}
}
}
}
}
我错过了什么?
嗯..没有什么是不正确的。由于您使用的是 draft-07,您可以尝试用 if/then/else 编写它,看看错误是否更有帮助。
但是...
您确定您使用的实现理解 draft-07 吗?如果它通过 draft-04 规则忽略 $schema 和 运行 它,它就不会理解 const
。您应该为此检查您的工具文档。
这是我自己的错字……constant
应该是 const
。 :facepalm:
根据草案 7
It should be noted that const is merely syntactic sugar for an enum with a single element, therefore the following are equivalent:
{ "const": "United States of America" }
{ "enum": [ "United States of America" ] }
有些人可能会发现提供 default
键在某些渲染表单解决方案中用于选择单个选项时很有用。
我有一个对象,它提供一种资产版本的审计日志。它的几个属性(versionSource.metadata
和 versionSource.files
)是应该根据其中一个属性的值根据两个模式之一进行验证的对象。我开始在我的子模式中使用常量(在 oneOf
内,但那是说所有子模式都经过验证(因此打破了 oneOf
,因为不止一个经过验证。将其更改为不过,单值枚举有效。
为什么验证不同?
这是原始架构:
{
"$id": "https://example.com/schemas/asset-version.json",
"title": "Audit log of asset versions",
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"required": [
"assetID",
"version",
"versionSource"
],
"properties": {
"assetID": {
"type": "string"
},
"version": {
"type": "integer",
"minimum": 1
},
"versionSource": {
"type": "object",
"properties": {
"metadata": {
"type": "object",
"oneOf": [
{
"properties": {
"sourceType": { "constant": "client" }
}
},
{
"$ref": "#/definitions/version-source-previous-version"
}
]
},
"files": {
"type": "object",
"oneOf": [
{
"properties": {
"sourceType": { "constant": "upload" },
"sourceID": {
"type": "string"
}
}
},
{
"$ref": "#/definitions/version-source-previous-version"
}
]
}
}
}
},
"definitions": {
"version-source-previous-version": {
"properties": {
"sourceType": { "constant": "previous-version" },
"sourceID": {
"type": "integer",
"minimum": 1
}
}
}
}
}
这是一份示例文档:
{
"assetID": "0150a186-068d-43e7-bb8b-0a389b572379",
"version": 1,
"versionSource": {
"metadata": {
"sourceType": "client"
},
"files": {
"sourceType": "upload",
"sourceID": "54ae67b0-3e42-464a-a93f-3143b0f078fc"
}
},
"created": "2018-09-01T00:00:00.00Z",
"lastModified": "2018-09-02T12:10:00.00Z",
"deleted": "2018-09-02T12:10:00.00Z"
}
还有一个:
{
"assetID": "0150a186-068d-43e7-bb8b-0a389b572379",
"version": 2,
"versionSource": {
"metadata": {
"sourceType": "previous-version",
"sourceID": 1
},
"files": {
"sourceType": "previous-version",
"sourceID": 1
}
},
"created": "2018-09-01T00:00:00.00Z",
"lastModified": "2018-09-02T12:10:00.00Z",
"deleted": "2018-09-02T12:10:00.00Z"
}
这是我得到的错误:
消息:JSON 对来自 'oneOf' 的多个模式有效。有效的架构索引:0、1。 架构路径: https://example.com/schemas/asset-version.json#/properties/versionSource/properties/metadata/oneOf
由于 sourceType
在 oneOf
的两个模式中都是常量,我真的不确定我的对象如何对这两个模式有效。
不过,将架构更改为以下内容有效:
{
"$id": "https://example.com/schemas/asset-version.json",
"title": "Audit log of asset versions",
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"required": [
"assetID",
"version",
"versionSource"
],
"properties": {
"assetID": {
"type": "string"
},
"version": {
"type": "integer",
"minimum": 1
},
"versionSource": {
"type": "object",
"properties": {
"metadata": {
"type": "object",
"oneOf": [
{
"properties": {
"sourceType": { "enum": [ "client" ] }
}
},
{
"$ref": "#/definitions/version-source-previous-version"
}
]
},
"files": {
"type": "object",
"oneOf": [
{
"properties": {
"sourceType": { "enum": [ "upload" ] },
"sourceID": {
"type": "string"
}
}
},
{
"$ref": "#/definitions/version-source-previous-version"
}
]
}
}
}
},
"definitions": {
"version-source-previous-version": {
"properties": {
"sourceType": { "enum": [ "previous-version" ] },
"sourceID": {
"type": "integer",
"minimum": 1
}
}
}
}
}
我错过了什么?
嗯..没有什么是不正确的。由于您使用的是 draft-07,您可以尝试用 if/then/else 编写它,看看错误是否更有帮助。
但是...
您确定您使用的实现理解 draft-07 吗?如果它通过 draft-04 规则忽略 $schema 和 运行 它,它就不会理解 const
。您应该为此检查您的工具文档。
这是我自己的错字……constant
应该是 const
。 :facepalm:
根据草案 7
It should be noted that const is merely syntactic sugar for an enum with a single element, therefore the following are equivalent:
{ "const": "United States of America" }
{ "enum": [ "United States of America" ] }
有些人可能会发现提供 default
键在某些渲染表单解决方案中用于选择单个选项时很有用。