如何为自定义猫鼬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 . . .
}

我试着阅读文档来学习如何为自定义模式类型创建自定义验证方法,但我没有成功地尝试工作,到目前为止,我在网上没有找到任何例子。

我怎么能有一个自定义验证器永久链接到我的uidv4自定义模式类型,它将评估试图保存的数据,并在适当的时候返回我的自定义错误消息?

通过点击mongoose SchemaTypes文档中的链接并深入研究一些mongoose插件的源代码,我找到了答案。

本质上,要创建一个普遍应用于猫鼬SchemaType的所有实例的自定义验证器,应该将验证器直接传递给SchemaType的validate()方法。

在自定义SchemaType类定义中,可以通过调用类构造函数中父类的验证器方法来完成。下面是一个例子:

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. . .
}

如文档(以及我最初的问题)所示,猫鼬验证器接受包含validatormessage的对象{}。虽然它们经常被添加到模式中以为特定字段/路径提供自定义验证,但是它们可以通过调用SchemaType.validate()(其中schemaType被实际的schemaType名称替换,即String)并将验证器函数和消息作为两个单独的参数传递到schemaType的总体验证中。

对于那些使用自定义SchemaTypes的人,例如在我的用例中,通过让cast()方法始终返回true,并且只处理save()上的验证,可以从验证器获得所需的错误消息。

最新更新