Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

like image 863
Micah Bala Avatar asked Apr 20 '19 10:04

Micah Bala


2 Answers

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)
}
like image 70
Shivam Verma Avatar answered Jan 03 '23 16:01

Shivam Verma


Here is the way i use express-validator. I have a file validator.js where i have validation logic for many routes. For example:

validator.js

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

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

exports.anotherRoute = [// check data];

exports.doSomethingElse = [// check data];

Now in your route file you require the validator.js file
const validator = require("./validator"); // or where your file is located
and use the validation logic you want as a middleware. For example:

route.js

//

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

Last, inside your controller you have to check for possible errors created during validation, after requiring validationResult.

controller.js

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


exports.createUser(req, res) {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
        return res.status(422).json({ errors: errors.array() });
    }
    // do stuff here.

}

Also, you don't have to use app.use(expressValidator); in your server.js file

like image 24
dimitris tseggenes Avatar answered Jan 03 '23 14:01

dimitris tseggenes