javascript - 如何为自定义 mongoose SchemaType 的所有实例提供默认验证?
问题描述
我已按照 mongoose 文档创建自定义模式类型。我的实现是功能性的,但没有产生我想要的结果。
我的目标是拥有一个自定义 schemaType,它在转换失败(或转换成功但验证失败时)提供自定义错误消息,而无需在每次在我的 api 模式中使用数据类型时声明验证方法。
这是一个示例(我将尝试在评论中解释):
const mongoose = require('mongoose')
// Create Custom Schema Type
class UUIDv4 extends mongoose.SchemaType {
constructor(key, options) {
super(key, options, 'UUIDv4');
}
cast(val) {
if (/*Do UUIDv4 validation check here*/) {
/* Because of the way mongoose works, this error message is difficult
to present to a user because the built-in casting error message is
always used at the top level.
*/
throw new Error(`${val} is not a valid version 4 UUID`);
}
return val;
}
}
// Add `UUIDv4` to the type registry
mongoose.Schema.Types.UUIDv4 = UUIDv4;
const entitySchema = new mongoose.Schema({
entityKey: {
type: UUIDv4,
required: true
}
})
const Entity = mongoose.model('Entity', entitySchema)
const testEntity = new Entity({
entityKey: "123456789"
})
testEntity.save().then(() => {
console.log('done')
}).catch((e) => {
console.log(e.errors.entityKey.reason.message) // This is where the custom message can be found
})
显然,我可以跳过创建自定义 SchemaType,但我希望避免每次在我的模式中使用 entityKey 时都必须指定自定义验证器(它们被大量使用)。
const UUIDv4Validator = {
validator: function(v) {
// If is valid. . . return true
// else return false
},
message: 'Invalid UUIDv4'
}
const entitySchema = new mongoose.Schema({
entityKey: {
type: String,
required: true,
validate: UUIDv4Validator // I don't want to have to do this every time
}
})
我知道我可以保留自定义模式类型并使用可选的链接运算符在我的 try/catch 语句中检查是否存在此错误,但我宁愿避免这种需要,因为它会重复:
try {
// do stuff . . .
await testEntity.save()
} catch (e) {
const message = e?.errors?.entityKey?.reason?.message ?? e.message. // No thank you!
// do stuff . . .
}
我尝试阅读文档以了解如何为自定义模式类型创建自定义验证方法,但我未能成功尝试任何工作,到目前为止我还没有在网上找到任何示例。
如何将自定义验证器永久链接到我的 UUIDv4 自定义架构类型,该验证器将评估尝试保存的数据,并在适当时返回我的自定义错误消息?
解决方案
我通过点击 mongoose SchemaTypes 文档中的链接并挖掘一些 mongoose 插件的源代码找到了答案。
本质上,要制作一个普遍应用于 mongoose SchemaType 的所有实例的自定义验证器,应该将验证器直接传递给 SchemaType 的 validate() 方法。
在自定义的 SchemaType 类定义中,可以通过在类构造函数中调用 super 的验证器方法来完成。这是一个例子:
class UUIDv4 extends mongoose.SchemaType {
constructor(key, options) {
super(key, options, 'UUIDv4');
// Call the validate method of super and pass in a validator
// function and a message to return when validation fails
this.validate(function(val){
return isUUIDv4(val) // Example UUIDv4 validation check
}, '{PATH}: "{VALUE}" is not a valid version 4 UUID')
}
// Other class methods such as cast(), etc. . .
}
如文档(以及我的原始问题)中所示,猫鼬验证器接受{}
包含 avalidator
和 a的对象message
。尽管它们经常被添加到模式中以提供对特定字段/路径的自定义验证,但可以通过调用SchemaType.validate()
(其中 SchemaType 被实际的 SchemaType 名称,即 String 替换)并传入验证器函数,将它们添加到 schemaType 的整体验证中和消息作为两个单独的参数。
对于那些使用自定义 SchemaTypes 的人,例如在我的用例中,可以通过让cast()
方法始终返回 true 并仅处理save()
.
推荐阅读
- java - 如何将方法作为带参数的函数传递?
- javascript - 是否可以读取脚本值?
- cookies - Hybris 在注销时删除特定的 cookie
- javascript - TypeScript 条件类型和计算对象属性名称
- python - 多元二阶多项式回归python
- kotlin - 找到列表中超出某个索引并满足某些条件的第一个元素
- python - IndentationError: unindent 不匹配任何外部缩进级别(我在此站点上发现的内容没有帮助)
- arrays - 有条件地选择逐列或逐行迭代
- azure - 数据在 Azure 时序见解中同时进入暖存储和冷存储
- amazon-web-services - 无法访问 ec2 内的 Web 服务器