如何将参数传递给自定义express-validator?

时间:2018-07-18 22:02:05

标签: node.js 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)
         });
    });
  })
]
....

我如何通过用户?

2 个答案:

答案 0 :(得分:2)

express-validator只知道请求对象本身,这使得最终用户的复杂性非常低。
更重要的是,它仅真正了解请求的输入位置-bodycookiesheadersqueryparams

您的自定义验证程序是完全正确的。话虽如此,它可能无法测试,因为您似乎依赖于全局上下文。

为了使其可测试,我看到的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。编写一个工厂函数以返回您的验证程序的实例:

这是我的首选解决方案,因为它不再涉及使用请求对象。

// 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');

希望这会有所帮助!

答案 1 :(得分:1)

将我的评论转换成最终的最终答案:

验证器只是应该根据给定的数据类型/长度/模式条件验证请求实体的字段。

您需要自己编写该方法,以确定用户是否预先存在。如果项目存在于您的项目列表(或数据源)中,则快速验证器(或更确切地说是任何验证器)不会执行挑选任务,也不应与相关数据源进行交互。