My Express API exposes a POST endpoint to create a user, and i need to validate data before inserting it into database, i have two methods in mind:
Method 1: Include the model's validation in the controller and repeat it for every model:
// controllers/users.js
exports.createUser = async function (req, res) {
const { username, email, password } = req.body;
/* validation logic */
/* interact with db */
Method 2: Move the validation logic to dedicated middleware:
// middleware/validators.js
exports.validateArticle = function (req, res, next) {};
exports.validateComment = function (req, res, next) {};
exports.validateUser = function (req, res, next) {
const { username, email, password } = req.body;
/* validation logic */
if (!isValid) {
return res.statusCode(400);
}
next();
};
// routes/users.js
const { validateUser } = require('../middlewares/validators');
router.route('/').post(validateUser, createUser);
my concern with method 2 is that the logic for one endpoint method would be scattered among many files, but which one of these methods follow best practices ?
I can suggest you to use a ready-made middlewares express-validator, and setup like that:
// src/validation/validation.js
const { validationResult } = require('express-validator');
const validate = (schemas) => {
return async (req, res, next) => {
await Promise.all(schemas.map((schema) => schema.run(req)));
const result = validationResult(req);
if (result.isEmpty()) {
return next();
}
const errors = result.array();
return res.send({
message: 'Validation error',
errors: errors,
})
};
}
module.exports = {
validate
}
this is a function that you can call like middleware in your router, then a file with validation rules.
// src/validation/validationSchemas.js
const { body } = require('express-validator');
const addUserSchema = [
body('username').isLength({ min: 4, max: 16 }).withMessage('Username must be at least 4 and no more than 16 characters'),
body('email').isEmail().withMessage('Incorrect email')
];
module.exports = { addUserSchema }
and in your router:
const { validate } = require('../validation/validation');
const { registrationSchema, loginSchema } = require('../validation/validationSchemas');
router.post('/registration', validate(registrationSchema), userController.registration);
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