3.11 – Request Validation in Node.js

Learn how to validate user input in your Node.js application using Express Validator the right way—clean, maintainable, and scalable.

✅ Why Request Validation Matters

In real-world applications, you must validate user input to:

  • Ensure correct data is received.

  • Prevent server crashes or database errors.

  • Enhance user experience with meaningful error messages.


🗂 Step 1: Update the User Model

Let’s define a complete schema for our User model that includes validation requirements like required fields and default timestamps.

src/models/User.ts

sh
import * as mongoose from ‘mongoose’;
import { model } from ‘mongoose’;
const userSchema = new mongoose.Schema({
email: { type: String, required: true },
password: { type: String, required: true },
username: { type: String, required: true },
created_at: { type: Date, default: new Date(), required: true },
updated_at: { type: Date, default: new Date(), required: true }
});
export default model(‘users’, userSchema);

🧪 Step 2: Bad Approach – Manual Validation (NOT RECOMMENDED)

Here’s an example of manual validation in the controller. It works but becomes messy and repetitive as your app grows.

UserController.ts

sh
export class UserController {
static signup(req, res, next) {
const { username, email, password } = req.body;
if (!username) return next(new Error(‘Username is required’));
if (!email) return next(new Error(‘Email is required’));
if (!password) return next(new Error(‘Password is required’));
// Save user logic here…
}
}

❌ Problem:

  • Violates DRY principle (Don’t Repeat Yourself).

  • Clutters your controller.

  • Not scalable for larger forms.


✅ Step 3: Install Express Validator

Let’s use a better approach.

Run in terminal:

sh
npm install –save express-validator

🧱 Step 4: Create a Validator Layer

We’ll now create a validators folder and define rules for user registration.

src/validators/UserValidator.ts

sh
import { body } from ‘express-validator’;
export class UserValidators {
static signup() {
return [
body(‘username’, ‘Username is required’).isString(),
body(’email’, ‘Valid email is required’).isEmail(),
body(‘password’, ‘Password must be at least 6 characters long’).isLength({ min: 6 }),
];
}
}

🎯 You can even add custom validation using .custom() if needed later.


🔁 Step 5: Connect Validator to Router

Now we apply these validation rules before the controller logic runs.

UserRouter.ts

sh
import { UserValidators } from ‘../validators/UserValidator’;
import { UserController } from ‘../controllers/UserController’;
getRoutes() {
this.router.post(‘/signup’, UserValidators.signup(), UserController.signup);
}

🧠 Step 6: Handle Validation Results in Controller

Finally, in the controller, check if validation failed using validationResult.

UserController.ts

sh
import { validationResult } from ‘express-validator’;
import User from ‘../models/User’;
export class UserController {
static signup(req, res, next) {
const errors = validationResult(req);
if (!errors.isEmpty()) {
const firstError = errors.array()[0].msg;
return next(new Error(firstError));
}
const { username, email, password } = req.body;
const newUser = new User({ username, email, password });
newUser.save()
.then(user => res.status(201).json(user))
.catch(err => next(err));
}
}

✅ Final Test

Use Postman:

  • POST http://localhost:5000/api/user/signup

  • Body: x-www-form-urlencoded

You’ll receive validation errors if any fields are missing or invalid.

🧩 Summary

Step Description
1️⃣ Define schema with required fields
2️⃣ Avoid manual validation in controller
3️⃣ Use Express Validator for clean rules
4️⃣ Centralize all validation in a validator file
5️⃣ Handle errors using validationResult
6️⃣ Return readable error messages

 

Scroll to Top