README
get-validated
A simple, flexible validation middleware to make validation less painful
What is it?
get-validated is not a validation framework. Rather, it is a simple express middleware that allows you to integrate many validation frameworks into your express app in a consistent manner.
It comes with the validator framework built in.
All validation errors are combined and put into a single ValidationError
object
with a status|code of 412. And the messages
property is set to an object keyed
by parameter name of the current errors.
Basic Usage
Initial set up for a our little example express app.
var express = require('express'),
router = express.Router(),
get_validated = require('get-validated'),
validations
;
Once we have our express app all set then we create our validations object.
validations = get_validated({
'param1': function (value, container, done) {
// perform validation here.
// `value` will be the return from req.param('param1')
// `container` will be whatever is passed to `get_validated`
// `options` parameter as the `options.container` object
// It will also have a `helpers` object that will have
// the [`validator`](https://github.com/chriso/validator.js)
// framework attached.
if (!container.helpers.isInt(value)) {
return done(":name must be an integer, ':value' given");
}
if (value < 123) {
return done(":name must be greater than 123, ':value' given");
}
return done(null, container.helpers.toInt(value));
},
'param2': function (value, container, done) {
// you will have access to the current request via
// `container.req`
var req = container.req;
// You can do async things!
req.db.query('SELECT * FROM something where id = ?', [value],
function (err, rows) {
// ... do some validation here...
return done(':name value of :value could not be found!');
}
}
});
Now that we have our validations
object we can use it in a few different
ways.
- Apply it to the route and then use
req.getValidated
within individual route handlers.
router.use(validations);
router.route('/').post(function (req, res, next) {
req.getValidated(['param1','param2']).then(function (validated) {
//do something with the parameters.
console.log("Param1 = %s", validated.param1);
console.log("Param2 = %s", validated.param2);
// if you catch the error in this way a 412 error will be propagated
// to the client.
}).catch(next);
});
- Use it as route specific middleware to validate parameters used by
that route. Note: If you use this method then all errors are sent
to
next(err)
to be handled by your app's current error handler.
router.route('/').post([
validations.validate(['param1', 'param2']),
function (req, res) {
//do something with the parameters.
console.log("Param1 = %s", req.validated.param1);
console.log("Param2 = %s", req.validated.param2);
}
]);
Advanced Usage
Now one of the fun parts of this module is that you can integrate pretty much any validations framework that you want with it. Here is a list of some:
- [Composed Validations] (https://github.com/composed-validations/composed-validations)
- [Joi] (https://github.com/hapijs/joi)
- [validate-it] (https://github.com/vlkosinov/validate-it)
I'm going to use [Composed Validations] (https://github.com/composed-validations/composed-validations) here to show how you integrate a validation libray, at least one way to do it.
In Composed Validations examples they show an address validator, so let's work with that.
var cv = require('composed-validations');
var addressValidator = cv.struct()
.validate('street', cv.presence())
.validate('zip', cv.format(/\d{5}/) // silly zip format
.validate('city', cv.presence()
.validate('state', cv.presence();
So now that we have our address validator we can integrate it directly into our validations object like so
var options = {
container: {
'cv': cv, // we don't have to integrate but just for fun we will.
'addressValidator': addressValidator
}
};
var validations = get_validated({
'address': function (value, container, done) {
// we're going to ignore the value here because we have a complex type,
// but we'll get our reference to request to pull the values from there.
var req = container.req;
var address = {
street: req.param('street'),
zip: req.param('zip'),
city: req.param('city'),
state: req.param('state')
};
// and there we go, we don't have to worry about the error at this point
// because the validation handler will receive the thrown execption and
// turn it into a ValidationError appropriately.
container.addressValidator.test(address);
//but we do have to send our fancy validated address down to the user function.
return done(null, address);
}
}, options);
After we have our validations object we can use it just like any other one.
router.route('/').post([
validations.validate('address'),
function (req, res, next) {
// And our address information will be conveniently placed into the validated object.
console.log ("Address: %j", req.validated.address);
// do other stuff...
}
]);
options
container
- This is your integration point. Anything you attach here will be sent along to your validation functions as thecontainer
object.validateAction
- Don't like my validation handling function? Then write your own. Debugging is your responsibility.renderer
-get-validate
comes with a very simple message renderer that recognizes two tags (':name' and ':value'), provide your own function if you like.
todo
- route specific middleware
- more usage examples showing how to use the joi and composed-validations