How to implement validation in a separate file using express-validator

Micah Bala picture Micah Bala · Apr 20, 2019 · Viewed 7.7k times · Source

I am trying to use express-validator to validate the req.body before sending a post request to insert data to postgres.

I have a route file, controller file and I want to carryout validation in a file called validate.js. Meanwhile, I have installed express-validator and in my server.js I have imported it. Other resources I come across seem to implement the validation in the function that contains the logic for inserting the data.

//server.js
....
import expressValidator from 'express-validator';

...
app.use(bodyParser.urlencoded({ extended: false }));
app.use(expressValidator);

//route.js
import express from 'express';
import usersController from './controller';

const router = express.Router();

router.post('/createuser', usersController.createUser);

//controller.js
createUser(req, res){
  // ...
  const { firstName, lastName, email, password } = req.body;
  //code to insert user details to the database
}

//validator.js
import { check } from 'express-validator/check';

module.exports = [check('email').isEmail()];

I expect to implemet the validation in a file called validator.js to, say, validate the email before inserting to the database

Answer

Shivam Verma picture Shivam Verma · Apr 17, 2020

I have same approach, except one thing that is we shouldn't handle validation error in our controller. So If any error is occurring at Validation Layer, it should throw back from there only. We shouldn't allow our control flow to enter into the Controller Layer. So below are the code example:

useRoute.js

const route = express.Router();

const {
  **validateUser**,
} = require('../middlewares/validators/userValidator');

route.route('/').post(**validateUser**, createUser);
route.route('/:id').put(**validateUser**, updateUser);

module.exports = route;

userValidator.js

const {check, validationResult} = require('express-validator');

exports.validateUser = [
  check('name')
    .trim()
    .escape()
    .not()
    .isEmpty()
    .withMessage('User name can not be empty!')
    .bail()
    .isLength({min: 3})
    .withMessage('Minimum 3 characters required!')
    .bail(),
  check('email')
    .trim()
    .normalizeEmail()
    .not()
    .isEmpty()
    .withMessage('Invalid email address!')
    .bail(),
  (req, res, next) => {
    const errors = validationResult(req);
    if (!errors.isEmpty())
      return res.status(422).json({errors: errors.array()});
    next();
  },
];

controller.js

/**
 * @desc    - create new User
 * @method  - POST
 */
exports.createCategory = async (req, res) => {
  //  do your stuff here. (No need to check any validation error here)
}