使用mongoose和express处理数据验证的最佳位置

时间:2013-12-09 07:34:56

标签: node.js express mongoose

也许这里没有确定的答案,但我想知道在处理express.js和mongoose时在哪里处理数据验证。以下哪项是最佳实践(我目前使用的是组合,并且开始感觉非常笨拙):

  1. 模特(猫鼬)
  2. 控制器/路线(快递)
  3. 我读过的一些旧帖子是:

    但是相互矛盾的答案只会增加混乱。也许它根本不是明确的,在这种情况下是一个更好的选择?

2 个答案:

答案 0 :(得分:7)

当使用mongoose时,我会将我的验证逻辑的大多数推送到mongoose模型/模式。您可以使用mongoose-validator作为简单模型验证的节点验证器的包装器。如果您需要在验证中针对其他模型或更复杂的逻辑进行验证,您可以编写自己的自定义mongoose预验证或发布验证挂钩(see mongoose middleware)。

使用mongoose验证模型时获得的另一个好处是,mongoose会为您的模型添加一个错误属性,可以通过model.errors[property]访问该属性。此属性可用于Web或服务客户端上的验证错误消息。

当编写更多/非常复杂的软件时,将验证绑定到模型可能会成为一个问题。但是当它出现时我会处理这个问题。由于JavaScript具有作为一等公民的功能,因此即使在这些复杂情况下,您的验证功能仍可以重复使用。

答案 1 :(得分:4)

mongoose验证器是一个在模型级别上启动的好地方,但是如果你需要特定于控制器的验证,我在utils.js文件中使用以下代码:

var async = require('async')
exports.validator = function (reqProps, props, mongoEnt, next) {
    var propsErr = [];
    var mongoErr = {};

    async.parallel([function (cb) {
        reqProps.forEach(function (rp) {
            if (!props[rp])propsErr.push(rp);
        })
        cb()
    }, function (cb) {
        if (mongoEnt != null) {
            var test = new mongoEnt(props);

            test.validate(function (err) {
                mongoErr = err;
                cb();
            });
        } else {
            mongoErr = null;
            cb();
        }
    }], function (err, result) {
        if (propsErr.length != 0) {
                return next(new Error('The following props were not included: ' + propsErr));
        } else if(mongoErr != null) {
                return next(new Error('The following prop was not included: ' +mongoErr.errors[Object.keys(mongoErr.errors).pop()].path));
        } else {
            return next(null);
        }
    })
}

这允许我使用mongoose验证器进行验证,并检查我在一行代码中包含在reqProps属性中的其他道具。虽然这只是检查所需的属性,但您可以轻松地将其扩展为您自己的验证方案。

此代码的使用示例:

var Person = mongoose.model('Person')

exports.addUSCitizen = function(props, next){ 
    utils.validator(['ssn'], props, Person, function (err) {
        if(err) return next(err);
        //do something using props.ssn
    })
}