Reusable Node Code Modules, Part 2 - Request Validation
Ensuring Data Integrity: Building Robust Request Validation Modules
Request validation is crucial for ensuring that incoming data meets specific criteria before processing it. Proper validation helps prevent errors, enhances security, and improves data integrity. This guide covers how to structure reusable request validation modules in Node.js and Express, manage validations efficiently, and integrate common libraries
Common Libraries and Tools
1. Joi
Joi is a powerful schema description language and data validator for JavaScript
Key Features
Schema-based validation
Rich validation rules
Custom error messages
Integration with Express
2. express-validator
express-validator is a set of Express.js middleware for validating and sanitizing user input
Key Features
Declarative validation syntax
Built-in sanitization
Custom validators and sanitizers
Integration with Express
3. Yup
Yup is a JavaScript schema builder for value parsing and validation
Key Features
Schema-based validation
Asynchronous validation support
Custom validation methods
Integration with various frameworks
4. Validator.js
Validator.js is a library for string validation and sanitization
Key Features
Comprehensive string validation
Built-in sanitization functions
Lightweight and flexible
Integration with other libraries
Comparison
Joi: Best for schema-based validation with rich validation rules and custom error messages
express-validator: Ideal for applications using Express, providing middleware for validation and sanitization
Yup: Suitable for schema-based validation with asynchronous support and custom methods
Validator.js: Best for lightweight string validation and sanitization
Examples
Example 1: Joi
Setup:
$ npm install joi
Middleware:
const Joi = require('joi');
const validateRequest = (schema) => (req, res, next) => {
const { error } = schema.validate(req.body);
if (error) {
return res.status(400).json({ error: error.details[0].message });
}
next();
};
module.exports = validateRequest;
Usage:
const express = require('express');
const validateRequest = require('./validateRequest');
const Joi = require('joi');
const userSchema = Joi.object({
name: Joi.string().min(3).required(),
email: Joi.string().email().required(),
password: Joi.string().min(6).required(),
});
const app = express();
app.use(express.json());
app.post('/register', validateRequest(userSchema), (req, res) => {
res.send('User registered successfully');
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
Example 2: express-validator
Setup:
$ npm install express-validator
Middleware:
const { validationResult, checkSchema } = require('express-validator');
const validateRequest = (schema) => [
checkSchema(schema),
(req, res, next) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
next();
},
];
module.exports = validateRequest;
Usage:
const express = require('express');
const validateRequest = require('./validateRequest');
const userSchema = {
name: {
in: ['body'],
isString: true,
isLength: {
options: { min: 3 },
},
errorMessage: 'Name must be at least 3 characters long',
},
email: {
in: ['body'],
isEmail: true,
errorMessage: 'Invalid email address',
},
password: {
in: ['body'],
isString: true,
isLength: {
options: { min: 6 },
},
errorMessage: 'Password must be at least 6 characters long',
},
};
const app = express();
app.use(express.json());
app.post('/register', validateRequest(userSchema), (req, res) => {
res.send('User registered successfully');
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
Example 3: Yup
Setup:
$ npm install yup
Middleware:
const yup = require('yup');
const validateRequest = (schema) => async (req, res, next) => {
try {
await schema.validate(req.body);
next();
} catch (error) {
res.status(400).json({ error: error.message });
}
};
module.exports = validateRequest;
Usage:
const express = require('express');
const validateRequest = require('./validateRequest');
const yup = require('yup');
const userSchema = yup.object().shape({
name: yup.string().min(3).required('Name is required'),
email: yup.string().email('Invalid email').required('Email is required'),
password: yup.string().min(6, 'Password must be at least 6 characters long').required('Password is required'),
});
const app = express();
app.use(express.json());
app.post('/register', validateRequest(userSchema), (req, res) => {
res.send('User registered successfully');
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
Example 4: Validator.js
Setup:
$ npm install validator
Middleware:
const { body, validationResult } = require('express-validator');
const validateRequest = (schema) => [
...schema,
(req, res, next) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
next();
},
];
module.exports = validateRequest;
Usage:
const express = require('express');
const validateRequest = require('./validateRequest');
const { body } = require('express-validator');
const userSchema = [
body('name').isString().isLength({ min: 3 }).withMessage('Name must be at least 3 characters long'),
body('email').isEmail().withMessage('Invalid email address'),
body('password').isString().isLength({ min: 6 }).withMessage('Password must be at least 6 characters long'),
];
const app = express();
app.use(express.json());
app.post('/register', validateRequest(userSchema), (req, res) => {
res.send('User registered successfully');
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});