AJV 6.5:请求对象需含query且仅可选0或1个指定属性的校验咨询
解决方案:AJV 6.5实现灵活的属性组合校验
针对你提到的AJV 6.5版本的校验需求,原来用maxProperties: 2的方案确实不够灵活——一旦后续要新增类似limit/count/max的可选属性,就得手动调整这个数值,维护成本很高。下面给你两种更优雅且可扩展的实现方式:
方法一:使用dependencies + not关键字(推荐,扩展性强)
这种方式通过依赖规则限制:当存在某一个可选属性时,禁止同时出现其他可选属性,同时保证query是必填项,并且不允许额外的未知属性。
{ "type": "object", "required": ["query"], "properties": { "query": { "type": "object" }, "limit": { "type": "integer" }, "count": { "type": "boolean" }, "max": { "type": "string" } }, "additionalProperties": false, "dependencies": { "limit": { "not": { "required": ["count", "max"] } }, "count": { "not": { "required": ["limit", "max"] } }, "max": { "not": { "required": ["limit", "count"] } } } }
规则说明:
required: ["query"]:强制请求对象必须包含query属性additionalProperties: false:禁止出现properties中未定义的属性,避免非法字段混入dependencies部分:- 当存在
limit时,不能同时有count或max - 当存在
count时,不能同时有limit或max - 当存在
max时,不能同时有limit或count
- 当存在
扩展方式:
如果后续需要新增可选属性(比如min),只需要两步:
- 在
properties中新增min的类型定义:"min": { "type": "integer" } - 在
dependencies中新增一条规则:"min": { "not": { "required": ["limit", "count", "max"] } }
方法二:使用oneOf枚举所有合法组合(直观,适合属性较少的场景)
这种方式直接枚举所有允许的属性组合,每个组合都是独立的校验规则,可读性极强。
{ "type": "object", "oneOf": [ // 仅包含query的情况 { "required": ["query"], "properties": { "query": { "type": "object" } }, "additionalProperties": false }, // query + limit的情况 { "required": ["query", "limit"], "properties": { "query": { "type": "object" }, "limit": { "type": "integer" } }, "additionalProperties": false }, // query + count的情况 { "required": ["query", "count"], "properties": { "query": { "type": "object" }, "count": { "type": "boolean" } }, "additionalProperties": false }, // query + max的情况 { "required": ["query", "max"], "properties": { "query": { "type": "object" }, "max": { "type": "string" } }, "additionalProperties": false } ] }
规则说明:
oneOf关键字表示请求对象必须匹配其中恰好一个子规则- 每个子规则定义了一种合法的属性组合,确保不会出现多个可选属性共存的情况
扩展方式:
新增可选属性时,只需要在oneOf数组中新增一个对应的子规则即可,比如新增query + min的组合:
{ "required": ["query", "min"], "properties": { "query": { "type": "object" }, "min": { "type": "integer" } }, "additionalProperties": false }
验证效果
两种方案都能正确校验:
- 有效请求(仅
query,或query加一个可选属性)会通过校验 - 无效请求(
query同时加两个及以上可选属性)会被拦截
内容的提问来源于stack exchange,提问作者Geoff Paul Bremner
相关产品推荐
相关产品推荐

