使用 ajv 了解 JSON 架构错误
Understanding JSON Schema errors using ajv
我有以下架构和 json 使用 ajv 进行验证。
const schema = {
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [ "countries" ],
"definitions": {
"europeDef": {
"type": "object",
"required": ["type"],
"properties": { "type": {"const": "europe"} }
},
"asiaDef": {
"type": "object",
"required": ["type"],
"properties": { "type": {"const": "asia"} }
}
},
"properties": {
"countries": {
"type": "array",
"items": {
"oneOf":[
{ "$ref": "#/definitions/europeDef" },
{ "$ref": "#/definitions/asiaDef"}
]
}
}
}
}
const data = {
"countries":[
{"type": "asia"},
{"type": "europe1"}
]
}
const isValid = ajv.validate(schema, data); //schema, data
if(! isValid){
console.log(ajv.errors);
}
错误是:
[
{
keyword: 'const',
dataPath: '/countries/1/type',
schemaPath: '#/definitions/europeDef/properties/type/const',
params: { allowedValue: 'europe' },
message: 'should be equal to constant'
},
{
keyword: 'const',
dataPath: '/countries/1/type',
schemaPath: '#/definitions/asiaDef/properties/type/const',
params: { allowedValue: 'asia' },
message: 'should be equal to constant'
},
{
keyword: 'oneOf',
dataPath: '/countries/1',
schemaPath: '#/properties/countries/items/oneOf',
params: { passingSchemas: null },
message: 'should match exactly one schema in oneOf'
}
]
我知道为什么会出现错误(原因:因为我使用了'europe1',它不符合架构标准)
根据上述错误情况,我有以下问题:
是的,我提供了 'asia' 作为有效的 const,错误仍然在谈论 'asia' 作为数组中第二个条目的一部分。为什么它显示为错误,尽管从亚洲角度来看架构绝对没问题。这是因为 'oneOf' 习惯了吗?换句话说,很难理解,错误是什么,错误在哪里,什么不是?
对于亚洲,'消息:'should be equal to constant'(数组的第 2 项)在我看来是误导性的。给人的感觉是'asia'.
还是有些问题
如何解析这个错误:根据schemaPath还是dataPath?同样在任何情况下,它仍然会给人一种印象,即 'asia'(实际上不是)
方面存在问题
另外,如何向新手解释上面的错误输出,因为新手仍然会说,为什么asia是正确的却出现了错误的一部分?
此外,如果使用 oneOf/anyOf,allOf 或使用 if-then-else 使模式变得更复杂,则 ajv.errors 输出变得更难以理解和解释(当某些条件准确但显示为错误时,例如 asia here)
有什么theory/documentaion/guidelines可以更好地理解错误的方法吗?
对于 JSON 架构草案 2019-09,我们创建了几种标准化的输出格式。与许多库相比,ajv 提供了 draft-07 模式中最有用的输出之一。
查看错误时,您可能会忽略 dataPath
值。
1的回答,报的错误都是在数据路径/countries/1
上的应用。 /countries/0
没问题,如你所说。 javascript 中的数组从 0 开始。
我想知道这也可以回答您所有其他问题。
我认为您可能假设数组从 1 开始,并且数据路径指的是 asia
对象,而它实际上是针对 europe1
对象。
如果我遗漏了什么或者您对此仍然感到困惑,请发表评论。
我有以下架构和 json 使用 ajv 进行验证。
const schema = {
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [ "countries" ],
"definitions": {
"europeDef": {
"type": "object",
"required": ["type"],
"properties": { "type": {"const": "europe"} }
},
"asiaDef": {
"type": "object",
"required": ["type"],
"properties": { "type": {"const": "asia"} }
}
},
"properties": {
"countries": {
"type": "array",
"items": {
"oneOf":[
{ "$ref": "#/definitions/europeDef" },
{ "$ref": "#/definitions/asiaDef"}
]
}
}
}
}
const data = {
"countries":[
{"type": "asia"},
{"type": "europe1"}
]
}
const isValid = ajv.validate(schema, data); //schema, data
if(! isValid){
console.log(ajv.errors);
}
错误是:
[
{
keyword: 'const',
dataPath: '/countries/1/type',
schemaPath: '#/definitions/europeDef/properties/type/const',
params: { allowedValue: 'europe' },
message: 'should be equal to constant'
},
{
keyword: 'const',
dataPath: '/countries/1/type',
schemaPath: '#/definitions/asiaDef/properties/type/const',
params: { allowedValue: 'asia' },
message: 'should be equal to constant'
},
{
keyword: 'oneOf',
dataPath: '/countries/1',
schemaPath: '#/properties/countries/items/oneOf',
params: { passingSchemas: null },
message: 'should match exactly one schema in oneOf'
}
]
我知道为什么会出现错误(原因:因为我使用了'europe1',它不符合架构标准)
根据上述错误情况,我有以下问题:
是的,我提供了 'asia' 作为有效的 const,错误仍然在谈论 'asia' 作为数组中第二个条目的一部分。为什么它显示为错误,尽管从亚洲角度来看架构绝对没问题。这是因为 'oneOf' 习惯了吗?换句话说,很难理解,错误是什么,错误在哪里,什么不是?
对于亚洲,'消息:'should be equal to constant'(数组的第 2 项)在我看来是误导性的。给人的感觉是'asia'.
还是有些问题
如何解析这个错误:根据schemaPath还是dataPath?同样在任何情况下,它仍然会给人一种印象,即 'asia'(实际上不是)
方面存在问题
另外,如何向新手解释上面的错误输出,因为新手仍然会说,为什么asia是正确的却出现了错误的一部分?
此外,如果使用 oneOf/anyOf,allOf 或使用 if-then-else 使模式变得更复杂,则 ajv.errors 输出变得更难以理解和解释(当某些条件准确但显示为错误时,例如 asia here)
有什么theory/documentaion/guidelines可以更好地理解错误的方法吗?
对于 JSON 架构草案 2019-09,我们创建了几种标准化的输出格式。与许多库相比,ajv 提供了 draft-07 模式中最有用的输出之一。
查看错误时,您可能会忽略 dataPath
值。
1的回答,报的错误都是在数据路径/countries/1
上的应用。 /countries/0
没问题,如你所说。 javascript 中的数组从 0 开始。
我想知道这也可以回答您所有其他问题。
我认为您可能假设数组从 1 开始,并且数据路径指的是 asia
对象,而它实际上是针对 europe1
对象。
如果我遗漏了什么或者您对此仍然感到困惑,请发表评论。