我们如何将参数传递给自定义快速验证器?
how can we pass parameter to custom express-validator?
我想阻止使用已经存在的电子邮件地址进行注册。是否可以为此使用 express-validator 的新语法?例如:
router.post('/register', [
check('email').custom((value, {req}) => {
return new Promise((resolve, reject) => {
Users.findOne({email:req.body.email}, function(err, user){
if(err) {
reject(new Error('Server Error'))
}
if(Boolean(user)) {
reject(new Error('E-mail already in use'))
}
resolve(true)
});
});
})
]
....
我将如何通过用户?
在这里将我的评论转化为最终的结论性答案:
验证器只是应该根据给定的数据类型/长度/模式标准验证请求实体的字段。
您需要自己编写方法来确定用户是否预先存在。如果该项目存在于您的项目列表(或您的数据源)中,则快速验证器(或更确切地说是任何验证器)不会执行挑选任务,也不应与相关数据源交互。
express-validator 只知道请求对象本身,这使得最终用户的复杂性非常低。
更重要的是,它只真正知道请求的输入位置——body
、cookies
、headers
、query
和 params
.
您的自定义验证器完全正确。话虽这么说,它 可能无法测试 ,因为您似乎依赖于全局上下文。
为了使其可测试,我看到的 2 个选项是:
1。注入 req.Users
:
这将涉及使用一些中间件将您的商店对象设置到 req
:
// Validator definition
const emailValidator = (value, { req }) => {
return req.Users.findOne({ email: value }).then(...);
}
// In production code
// Sets req.Users, req.ToDo, req.YourOtherBusinessNeed
app.use(myObjectsStore.middleware);
app.post('/users', check('email').custom(emailValidator));
// In tests
req = { Users: MockedUsersObject };
expect(emailValidator('foo@bar.com', { req })).rejects.toThrow('email exists');
2。编写一个 returns 验证器实例的工厂函数:
这是我的首选解决方案,因为它不再涉及使用请求对象。
// Validator definition
const createEmailValidator = Users => value => {
return Users.findOne({ email: value }).then(...);
};
// In production code
app.post('/users', [
check('email').custom(createEmailValidator(myObjectsStore.Users)),
]);
// Or in tests
expect(createEmailValidator(MockedUsersObject)('foo@bar.com')).rejects.toThrow('email exists');
希望对您有所帮助!
我想阻止使用已经存在的电子邮件地址进行注册。是否可以为此使用 express-validator 的新语法?例如:
router.post('/register', [
check('email').custom((value, {req}) => {
return new Promise((resolve, reject) => {
Users.findOne({email:req.body.email}, function(err, user){
if(err) {
reject(new Error('Server Error'))
}
if(Boolean(user)) {
reject(new Error('E-mail already in use'))
}
resolve(true)
});
});
})
]
....
我将如何通过用户?
在这里将我的评论转化为最终的结论性答案:
验证器只是应该根据给定的数据类型/长度/模式标准验证请求实体的字段。
您需要自己编写方法来确定用户是否预先存在。如果该项目存在于您的项目列表(或您的数据源)中,则快速验证器(或更确切地说是任何验证器)不会执行挑选任务,也不应与相关数据源交互。
express-validator 只知道请求对象本身,这使得最终用户的复杂性非常低。
更重要的是,它只真正知道请求的输入位置——body
、cookies
、headers
、query
和 params
.
您的自定义验证器完全正确。话虽这么说,它 可能无法测试 ,因为您似乎依赖于全局上下文。
为了使其可测试,我看到的 2 个选项是:
1。注入 req.Users
:
这将涉及使用一些中间件将您的商店对象设置到 req
:
// Validator definition
const emailValidator = (value, { req }) => {
return req.Users.findOne({ email: value }).then(...);
}
// In production code
// Sets req.Users, req.ToDo, req.YourOtherBusinessNeed
app.use(myObjectsStore.middleware);
app.post('/users', check('email').custom(emailValidator));
// In tests
req = { Users: MockedUsersObject };
expect(emailValidator('foo@bar.com', { req })).rejects.toThrow('email exists');
2。编写一个 returns 验证器实例的工厂函数:
这是我的首选解决方案,因为它不再涉及使用请求对象。
// Validator definition
const createEmailValidator = Users => value => {
return Users.findOne({ email: value }).then(...);
};
// In production code
app.post('/users', [
check('email').custom(createEmailValidator(myObjectsStore.Users)),
]);
// Or in tests
expect(createEmailValidator(MockedUsersObject)('foo@bar.com')).rejects.toThrow('email exists');
希望对您有所帮助!