Where to validate in Express.js project – Validati

2019-04-14 22:48发布

问题:

I am writing an application with a form in Express.js, and to begin with, I was doing all of my validation in the route (or controller, if you like):

app.post('/register', function (req, res, next) {
  // Generic validation
  req.assert('name', 'Name is empty').notEmpty();
  req.assert('username', 'Username is empty').notEmpty();
  var errors = req.validationErrors(true);
  if (errors) {
    // If there are errors, show them
  } else {
    // If there are no errors, use the model to save to the database
  }
});

However, I quickly learnt that my validation should be happening in the model, keeping inline with the "thin controller, fat model" principle.

Model:

var userSchema = new Schema({
    name: {
      type: String
    , required: true
    , validate: [validators.notEmpty, 'Name is empty']
    }
  , username: {
      type: String
    , required: true
    , validate: [validators.notEmpty, 'Username is empty']
    }
 , salt: String
 , hash: String
});

Route/controller:

app.post('/register', function (req, res, next) {
  var newUser = new User(req.body);
  // Tell the model to try to save the data to the database
  newUser.save(function (err) {
    if (err) {
      // There were validation errors
    } else {
      // No errors
    }
  });
});

This works well. However, I need to do validation prior to the database layer. For instance, I need to check if two passwords are the same (password and confirmPassword). This cannot be defined in the schema, as I am only saving salt and hash in the model. Therefore, I need to do this validation before the database layer, in the route/controller. Because of this, I will not be able to display validation messages together.

Is this the best way thing to do things – validating in the model at the database layer, as well as in the controller? Is it better to have all of my validation in the controller like before? But then I will be repeating code where I save to the model again. Or should I use another pattern, and if so, what?

回答1:

I would consider moving the validation logic to the Model but stop thinking of the Model as the database. The model is greater than the database. The model performs the validation, and if the validation passes it saves the data to the database, if the validation fails it returns the correct messages so that a router can render the proper error messages.