JSON模式/Ajv-如何验证字符串数组的组合长度



假设我需要验证订单的发货地址:

{ "id": 1
, "recipient": "John Doe"
, "shipping_address": [ "address line 1"
, "address line 2"
, "address line 3"
]
}

地址的规则是:

  1. 字符串数组
  2. 至少一个字符串(并且可以根据需要具有任意多个字符串(
  3. 所有字符串的组合长度不得超过X个字符(例如50个(

我可以实现1&2,具有以下JSON模式:

{ "type": "array"
, "items": { "type": "string" }
, "minItems": 1
}

问题:如何使用JSON Schema/Ajv实现条件3

我找到了一个使用Ajv自定义关键字设计以下模式的解决方案:

{ "type": "array"
, "items": { "type": "string" }
, "minItems": 1
, "maxCombinedLength": 50
}

诀窍是在Ajv:中添加对maxCombinedLength的支持

ajv.addKeyword("maxCombinedLength", {
validate: (schema, data) => {
return data.reduce((l, s) => l + s.length, 0) <= schema;
}
});

其中:

  1. ajv是Ajv的一个实例
  2. schema就是50
  3. datashipping_address阵列

演示

const validate =
ajv.compile({ type: 'array'
, items: { type: 'string' }
, minItems: 1
, maxCombinedLength: 50
});
console.log(
validate([]));
// false (need at least one item)
console.log(
validate([ "address line 1"
, "address line 2"
, "address line 3"
]));
// true
console.log(
validate([ "address line 1"
, "address line 2"
, "address line 3"
, "address line 4"
, "address line 5"
, "address line 6"
, "address line 7"
, "address line 8"           
])
, validate.errors);
// false (maxCombinedLength not satisfied!)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ajv/6.12.0/ajv.min.js"></script>
<script>
const ajv = new Ajv;
ajv.addKeyword("maxCombinedLength", {
validate: (schema, data, parent_schema) => {
return data.reduce((l, s) => l + s.length, 0) <= schema;
}
});
</script>


附录:如何忽略非字符串数组

显然,我们不能将maxCombinedLength与对象数组一起使用。

值得庆幸的是,Ajv允许我们访问父模式:

ajv.addKeyword("maxCombinedLength", {
validate: (schema, data, parent_schema) => {
if (parent_schema.items.type === 'string') {
return data.reduce((l, s) => l + s.length, 0) <= schema;
} else {
return true;
}
}
});

因此,使用以下模式:

{ "type": "array"
, "items": { "type": "string" }
, "minItems": 1
, "maxCombinedLength": 50
}

自定义关键字函数将接收50作为schema参数,接收数组作为data参数,接收完整模式作为parent_schema参数。

parent_schema参数用于查询数组的类型。如果我们不需要字符串,我们可以通过返回true来取消maxCombinedLength关键字。

相关内容

  • 没有找到相关文章

最新更新