I'm trying to keep my controller actions as lightweight as possible so i am implementing service layer. Now i've stucked with validation and sanitization. I know that validation should be done in service layer but what about sanitization? I would like to re-render the with the input data when there are validation errors.
//userService.js function
function register(data, callback) {
if (!data) {
return callback(new Error('Here some error...'));
}
/* Sanitize and validate the data */
/* Method #1 */
//If not valid then call back with validationErrors
if (notValid) {
return callback({
validationErrors: {
'username': 'Username is already in use.',
'email': 'Invalid characters.',
}
});
}
/* Method #2 */
if (notValid) {
return callback({
fields: {
//We put here a sanitized fields
},
validationErrors: {
'username': 'Username is already in use.',
'email': 'Invalid characters.',
}
});
}
};
//userController.js function
// GET/POST: /register
function registerAction(request, response, next) {
if (request.method === 'POST') {
var registerData = {
username: request.body['username'],
password: request.body['password'],
email: request.body['email'],
firstName: request.body['firstName'],
lastName: request.body['lastName'],
};
register(registerData, function(error, someDataIfSucceed) {
if (error) {
//Re-post the data so the user wont have to fill the form again
//Sanitize registerData variable here.
return response.render('register', {
error: error,
validationErrors: error.validationErrors
});
};
//User registered succesfully.
return response.render('registerSuccess');
});
return;
}
return response.render('register');
}
I see there 2 options.
If you're using Express, an interesting option is:
Create a middleware and use it as a validation layer, using express-validator, which is based on node-validator. For example (see node-validator documentation for all validation/sanitization options):
exports.validate = function(req, res, next) {
req.assert('username').notEmpty();
req.assert('password').notEmpty();
req.assert('email').isEmail();
req.assert('firstName').len(2, 20).xss();
req.assert('lastName').len(2, 20).xss();
var errors = req.validationErrors(true);
if (errors){
res.status(400).json({ status: 'ko', errors: errors });
}
else {
next();
}
}
Then, in your controller, simply obtain the validated request params and run the sign up logic (your register
function call and response rendering),
IMHO, this way you can keep your code more clean and decoupled.
If it's a small project don't bother, just do what works.
If, however, it is a large (read: long-lived) project, then:
If by "sanitization" you mean HTTP/HTML sanitization (or inputs, or of display messages), then this belongs in the controller. Think about it this way: the controller may not be the only place where you pass input to your service layer from. In the future you might have API access to the service. Or a test driver may invoke it directly, without going thru HTTP. So HTTP/HTML is just the transport, and as such logic specific to it should be outside of the service.
If, however, by "sanitization" you mean business-logic sanitization (e.g.: you don't allow non-existing country codes), then by all means this should be in the service, for exactly the same reasons.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With