An express.js middleware for validator.
- Upgrade notice
- Installation
- Usage
check
APIfilter
API- Sanitization Chain API
- Validation Chain API
- Validation Result API
- Legacy API
- Changelog
- License
If you're arriving here as a express-validator v3 user after upgrading to v4, please check the upgrade guide in order to find out what's different!
npm install express-validator
Also make sure that you have Node.js 6 or newer in order to use it.
The version 3 style of doing validations is still available.
Please check the legacy API for the docs.
const { check, validationResult } = require('express-validator/check');
const { matchedData, sanitize } = require('express-validator/filter');
app.post('/user', [
check('username')
// Every validator method in the validator lib is available as a
// method in the check() APIs.
// You can customize per validator messages with .withMessage()
.isEmail().withMessage('must be an email')
// Every sanitizer method in the validator lib is available as well!
.trim()
.normalizeEmail()
// ...or throw your own errors using validators created with .custom()
.custom(value => {
return findUserByEmail(value).then(user => {
throw new Error('this email is already in use');
})
}),
// General error messages can be given as a 2nd argument in the check APIs
check('password', 'passwords must be at least 5 chars long and contain one number')
.isLength({ min: 5 })
.matches(/\d/),
// No special validation required? Just check if data exists:
check('addresses.*.street').exists(),
// Wildcards * are accepted!
check('addresses.*.postalCode').isPostalCode(),
// Sanitize the number of each address, making it arrive as an integer
sanitize('addresses.*.number').toInt()
], (req, res, next) => {
// Get the validation result whenever you want; see the Validation Result API for all options!
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.mapped() });
}
// matchedData returns only the subset of data validated by the middleware
const user = matchedData(req);
createUser(user).then(user => res.json(user));
});
These methods are all available via require('express-validator/check')
.
field
: a string or an array of strings of field names to validate against.message
(optional): an error message to use when failed validators don't specify a message. Defaults toInvalid value
.
Returns: a Validation Chain
Creates a validation chain for one or more fields. They may be located in any of the following request objects:
req.body
req.cookies
req.headers
req.params
req.query
If any of the fields are present in more than one location, then all instances of that field value must pass the validation.
The validators will always be executed serially for the same field.
This means that if the chain targets more than one field, those will run in parallel, but each of their validators are serial.
Same as check(fields[, message])
, but only checking req.body
.
Same as check(fields[, message])
, but only checking req.cookies
.
Same as check(fields[, message])
, but only checking req.headers
.
Same as check(fields[, message])
, but only checking req.params
.
Same as check(fields[, message])
, but only checking req.query
.
validationChains
: an array of validation chains created withcheck()
or any of its variations, or an array of arrays containing validation chains.message
(optional): an error message to use when all chains failed. Defaults toInvalid value(s)
.
Returns: a middleware instance
Creates a middleware instance that will ensure at least one of the given chains passes the validation.
If none of the given chains passes, an error will be pushed to the _error
pseudo-field,
using the given message
, and the errors of each chain will be made available under a key nestedErrors
.
Example:
const { check, oneOf, validationResult } = require('express-validator/check');
app.post('/start-freelancing', oneOf([
check('programming_language').isIn(['javascript', 'java', 'php']),
check('design_tools').isIn(['photoshop', 'gimp'])
]), (req, res, next) => {
try {
validationResult(req).throw();
// yay! we're good to start selling our skilled services :)))
res.json(...);
} catch (err) {
// Oh noes. This user doesn't have enough skills for this...
res.status(422).json(...);
}
});
If an item of the array is an array containing validation chains, then all of those must pass in order for this group be considered valid:
// This protected route must be accessed either by passing both username + password,
// or by passing an access token
app.post('/protected/route', oneOf([
[
check('username').exists(),
check('password').exists()
],
check('access_token').exists()
]), someRouteHandler);
The execution of those validation chains are made in parallel,
while the execution within a chain still respects the rule defined in the check()
function.
req
: the express request object.
Returns: a validation result object
Extracts the validation errors from a request and makes it available in the form of a validation result object.
These methods are all available via require('express-validator/filter')
.
req
: the express request object.options
(optional): an object which accepts the following options:onlyValidData
: if set tofalse
, the returned value includes data from fields that didn't pass their validations. Defaults totrue
.locations
: an array of locations to extract the data from. The acceptable values includebody
,cookies
,headers
,param
andquery
. Defaults toundefined
, which means all locations.
Returns: an object of data validated by the
check
APIs.
Extracts data validated by the check
APIs from the request and builds
an object with them. Nested paths and wildcards are properly handled as well.
// Suppose the request looks like this:
// req.query = { from: '2017-01-12' }
// req.body = { to: '2017-31-12' }
app.post('/room-availability', check(['from', 'to']).isISO8601(), (req, res, next) => {
const queryData = matchedData(req, { locations: ['query'] });
const bodyData = matchedData(req, { locations: ['body'] });
const allData = matchedData(req);
console.log(queryData); // { from: '2017-01-12' }
console.log(bodyData); // { to: '2017-31-12' }
console.log(allData); // { from: '2017-01-12', to: '2017-31-12' }
});
field
: a string or an array of strings of field names to validate against.
Returns: a Sanitization Chain
Creates a sanitization chain for one or more fields. They may be located in any of the following request objects:
req.body
req.cookies
req.params
req.query
* req.headers
is not supported at the moment.
If any of the fields are present in more than one location, then all instances of that field value will be sanitized.
Same as sanitize(fields)
, but only sanitizing req.body
.
Same as sanitize(fields)
, but only sanitizing req.cookies
.
Same as sanitize(fields)
, but only sanitizing req.params
.
Same as sanitize(fields)
, but only sanitizing req.query
.
The sanitization chain is a middleware, and it should be passed to an Express route handler.
When the middleware runs, it will modify each field in place, applying each of the sanitizers in the order they were specified:
app.get('/', sanitizeBody('trimMe').trim(), (req, res, next) => {
// If req.body.trimMe was originally " something ",
// its sanitized value will be "something"
console.log(req.body.trimMe);
});
Any of the sanitization methods listed by validator.js are made available in all sanitization chains created by express-validator, as long as we're supporting the most up-to-date validator version.
Any of the validation and sanitization methods listed by validator.js are made available in all validation chains created by express-validator, as long as we're supporting the most up-to-date validator version.
If you use any of the sanitizers together with validators, the validated value is the sanitized one.
Additionally, the following methods are also available:
validator(value, { req, location, path })
: the custom validator function.
Receives the value of the field being validated, as well as the express request, the location and the field path.
Returns: the current validation chain instance
Adds a custom validator to the current validation chain.
The custom validator may return a promise to indicate an async validation task. In case it's rejected, the field is considered invalid.
The custom validator may also throw JavaScript exceptions (eg throw new Error()
) and return falsy values to indicate the field is invalid.
Example:
app.post('/create-user', [
check('password').exists(),
check('passwordConfirmation', 'passwordConfirmation field must have the same value as the password field')
.exists()
.custom((value, { req }) => value === req.body.password)
], loginHandler);
Returns: the current validation chain instance
Adds a validator to check for the existence of the current fields in the request.
This means the value of the fields may not be undefined
; any other values are acceptable.
Returns: the current validation chain instance
Negates the result of the next validator.
check('weekday').not().isIn(['sunday', 'saturday'])
options
(optional): an object of options to customize the optionality behaviour. Please check it below.
Returns: the current validation chain instance
Marks the current validation chain as optional.
This is useful to remove values that are not essential to your busines and that would cause validation failures in case they were not provided in the request.
By default, fields with undefined
values will be ignored from the validation.
You can further customize this behavior by passing an object with the following options:
nullable
: iftrue
, fields withnull
values will be considered optionalcheckFalsy
: iftrue
, fields with falsy values (eg""
,0
,false
,null
) will also be considered optional
message
: the error message to use for the previous validator
Returns: the current validation chain instance
Sets the error message for the previous validator.
This will have precedence over errors thrown by a custom validator.
This is an unified API for dealing with errors, both in legacy and check APIs.
Each error returned by .array()
and .mapped()
methods have the following format by default:
{
"msg": "The error message",
"param": "param.name.with.index[0]",
"value": "param value",
// Location of the param that generated this error.
// It's either body, query, params, cookies or headers.
"location": "body",
// nestedErrors only exist when using the oneOf function
"nestedErrors": [{ ... }]
}
Returns: a boolean indicating whether this result object contains no errors at all.
formatter(error)
: the function to use to format when returning errors.
Theerror
argument is an object in the format of{ location, msg, param, value, nestedErrors }
, as described above.
Returns: this validation result instance
options
(optional): an object of options. Defaults to{ onlyFirstError: false }
Returns: an array of validation errors.
Gets all validation errors contained in this result object.
If the option onlyFirstError
is set to true
, then only the first
error for each field will be included.
Returns: an object where the keys are the field names, and the values are the validation errors
Gets the first validation error of each failed field in the form of an object.
If this result object has errors, then this method will throw an exception decorated with the same validation result API.
try {
validationResult(req).throw();
// Oh look at ma' success! All validations passed!
} catch (err) {
console.log(err.mapped()); // Oh noes!
}
The "legacy API" is the same API used by version 3 and older releases of express-validator.
It's based around setting a global middleware in your express app and decorating the request object with new methods.
This API MUST NOT be used by new apps, since it may not receive new updates and can even be removed in a future major version.
You must mount the middleware in your app before you get access to the validation/sanitization methods:
const expressValidator = require('express-validator');
app.use(expressValidator(middlewareOptions));
errorFormatter (param, msg, value, location)
: a function that formats the error objects before returning them to your route handlers.customValidators
: an object where you can specify custom validators.
The key will be the name of the validator, while the value is the validation function, receiving the value and any option.customSanitizers
: an object where you can specify custom sanitizers.
The key will be the name of the sanitizer, while the value is the sanitization function, receiving the value and any option.
The Legacy Validation Chain instances provides further functionality than the one provided by the base Validation Chain objects.
It also differs in that the legacy one is not a middleware per se.
Any custom validator specified in the middleware will be made available in instances of this validation chain.
Additionally, the following validators are also available:
.notEmpty()
: alias of.isLength({ min: 1 })
.len()
: alias of.isLength()
field
: the name of a single field to validate against.message
(optional): an error message to use when failed validators don't specify a message. Defaults toInvalid value
.
Returns: a legacy validation chain
Creates a validation chain for one field. It may be located in any of the following request objects:
req.params
req.query
req.body
req.headers
req.cookies
If it's present in more than one location, then only the first one (following the above order) will be validated against.
This function is also aliased as
req.assert()
andreq.validate()
.
Same as req.check(field[, message])
, but only checking req.body
.
Same as req.check(field[, message])
, but only checking req.cookies
.
Same as req.check(field[, message])
, but only checking req.headers
.
Same as req.check(field[, message])
, but only checking req.params
.
Same as req.check(field[, message])
, but only checking req.query
.
Returns: a sanitizer chain
Creates a sanitizer chain that, when any of the sanitization methods is used, the return value is the sanitized value.
Also, the parameter is sanitized in-place; that is, in the below example,
req.body.comment
will be updated to the sanitized value.
const comment = req.sanitize('comment').trim();
console.log(comment === req.body.comment);
If the sanitized parameter is present in more than one location (eg req.query.comment
and req.body.comment
), the will all be sanitized.
This function is also aliased as
req.filter()
.
Same as req.sanitize(field[, message])
, but only sanitizing req.body
.
Same as req.sanitize(field[, message])
, but only sanitizing req.cookies
.
Same as req.sanitize(field[, message])
, but only sanitizing req.headers
.
Same as req.sanitize(field[, message])
, but only sanitizing req.params
.
Same as req.sanitize(field[, message])
, but only sanitizing req.query
.
Returns: a promise for a Validation Result object
Runs all validations and returns a validation result object for the errors gathered, for both sync and async validators.
mapped
(optional): whether the result must be an object instead of an array. Defaults tofalse
.
Returns: a promise which will resolve in case all validators passed, or reject with an array of errors or an object of errors (in case
mapped
argument istrue
).
Runs all validations and returns the errors gathered for all of them.
mapped
(optional): whether the result must be an object instead of an array. Defaults tofalse
.
Returns:
false
if no errors happened, an array of errors or an object of errors (in casemapped
argument istrue
).
Runs all validations and returns the errors gathered only for the completed validators.
This probably means any async validator will not be completed by the time this method responds.
All req.check
methods can do schema validation. This is a special way of validating data were you pass an object of your expected schema, and all the validations you want:
req.checkBody({
email: {
notEmpty: true,
isEmail: true
},
password: {
notEmpty: true,
matches: {
// more than one options must be passed as arrays
options: ['someregex', 'i'],
// single options may be passed directly
// options: /someregex/i
},
errorMessage: 'Invalid password'
},
// Wildcards and nested paths are supported as well
'name.first': {
optional: {
options: { checkFalsy: true }
}
},
termsAndConditionsAgreement: {
isBoolean: {
errorMessage: 'should be a boolean'
}
}
});
Check the GitHub Releases page.
MIT License