AJV JsonSchema校验器出现不符合预期的冗余报错如何优化
AJV anyOf校验冗余报错解决方案
问题根源
AJV校验anyOf关键字时,默认会遍历所有分支并返回所有分支的校验错误。你的场景中第二个数据项不匹配anyOf第一个分支的path规则,所以这部分无意义的错误也被返回。
解决方案
方案1:重构Schema,用if/then/else替代anyOf(推荐)
将path的匹配逻辑前置作为分支判断条件,只有path匹配对应规则时才会执行该分支下的value校验,从根源避免冗余错误产生。
修改后的Schema示例:
const schema = { type: 'array', minItems: 1, items: { type: 'object', required: ['op', 'path', 'value'], properties: { op: { enum: ['replace'] } }, allOf: [ { if: { properties: { path: { pattern: '/data/to/foo/bar' } } }, then: { properties: { value: { type: 'string' } } } }, { if: { properties: { path: { pattern: '/data/to/baz' } } }, then: { properties: { value: { type: 'object', required: ['foo', 'bar'], properties: { foo: { type: 'string' }, bar: { type: 'string' } } } } } } ] } }
修改后校验只会返回value缺少必填属性bar的核心错误,不会产生冗余的path不匹配报错。
方案2:事后过滤错误数组
如果不想调整现有Schema,可以对返回的errors数组做自定义过滤,剔除anyOf下非匹配分支的无效错误:
const filteredErrors = compiledValidator.errors.filter(err => { // 剔除anyOf第一个分支的path不匹配无效错误 return !err.schemaPath.includes('anyOf/0/properties/path/pattern') })
该方案为临时适配手段,兼容性和可维护性低于方案1。
方案3:开启discriminator配置(适用于path为固定枚举的场景)
如果你的path规则是固定值而非正则匹配,可以开启AJV的discriminator配置,自动匹配对应校验分支,仅返回对应分支的错误:
// 初始化时开启配置 const validator = new ajv({ discriminator: true })
同时将Schema中path字段改为枚举类型,指定discriminator字段为path即可。
内容的提问来源于stack exchange,提问作者Luke
相关产品推荐
相关产品推荐

