如何在JSON Schema的if/else中设置自定义错误消息及优化验证
JSON Schema验证优化问题
目标JSON结构
{ "authentication": { // provider是枚举类型,可选值为A和B。 // 若选择A,则jwt必须有值。 // 若选择B,则jwt必须无值 // JWT需包含3个必填属性:audience、issuer和baz "provider": "B", "jwt": { "audience": "foo", "issuer": "bar" } } }
当前使用的验证规则
"allOf": [ { "$comment": "We want the user to provide the JWT property when the provider requires it", "if": { "properties": { "provider": { "anyOf": [ { "const": "A" }, ] } }, "required": ["provider"] }, "then": { "required": ["jwt"] } }, { "$comment": "We want JWT property to be null when a provider does not require it. This reduces bugs and confusion.", "if": { "properties": { "provider": { "not": { "anyOf": [ { "const": "A" } ] } } }, "required": ["provider"] }, "then": { "properties": { "jwt": { "type": "null" } } } } ]
现有体验问题
- 出现关于jwt的警告:
Missing property "baz". - 出现关于audience和issuer的警告:
Incorrect type. Expected "null".
合理的错误提示应为“因所选provider,jwt不应有值”,现有提示不够明确。
待解决的问题
- 如何在
if/else中设置自定义错误消息? - 如何消除无关的“缺失baz属性”警告?
解决方案
1. 自定义if/else错误消息
JSON Schema官方规范未内置自定义错误消息字段,但多数主流验证库(如Ajv)支持通过扩展关键字(比如errorMessage)添加自定义提示。
直接在then块中添加errorMessage字段即可,示例:
{ "$comment": "provider为B时,jwt必须为null", "if": { "properties": { "provider": { "const": "B" } }, "required": ["provider"] }, "then": { "properties": { "jwt": { "type": "null" } }, "errorMessage": "因所选provider为B,jwt不应有值" } }
注意:使用该功能需确保验证库支持扩展关键字,比如Ajv需要启用ajv-errors插件。
2. 消除无关的“缺失baz属性”警告
问题根源是当provider为B时,验证器仍会校验jwt的内部结构。解决思路是仅在provider为A时,才启用jwt的完整结构验证;当provider为B时,只校验jwt是否为null,不触发内部属性验证。
调整后的完整验证规则示例:
"allOf": [ { "$comment": "provider为A时,jwt必填且符合完整结构", "if": { "properties": { "provider": { "const": "A" } }, "required": ["provider"] }, "then": { "required": ["jwt"], "properties": { "jwt": { "type": "object", "required": ["audience", "issuer", "baz"], "properties": { "audience": { "type": "string" }, "issuer": { "type": "string" }, "baz": { "type": "string" } // 根据实际数据类型调整 } } }, "errorMessage": "provider为A时,jwt必须包含audience、issuer和baz属性" } }, { "$comment": "provider为B时,jwt必须为null", "if": { "properties": { "provider": { "const": "B" } }, "required": ["provider"] }, "then": { "properties": { "jwt": { "type": "null" } }, "errorMessage": "因所选provider为B,jwt不应有值" } } ]
这样当provider为B时,验证器只会检查jwt是否为null,不会校验其内部属性,自然不会出现“缺失baz”的无关警告。
内容的提问来源于stack exchange,提问作者S. ten Brinke
相关产品推荐
相关产品推荐

