Skip to content

5. Input Validation

1. Input Validation Using Joi

Joi a powerful validation library that helps ensure incoming request data is correct and safe before using it.

1.1 πŸ” What is Joi?

Joi is an object schema description language and validator for JavaScript objects. It’s commonly used with Express to validate req.body, req.query, or req.params.

βœ… Install Joi

Terminal window
npm install joi

1.2 ✨ Basic Usage Example

Let’s validate a POST request where a user submits their name and age.

const express = require('express');
const Joi = require('joi');
const app = express();
app.use(express.json()); // Required to parse JSON bodies
// Define schema
const userSchema = Joi.object({
name: Joi.string().min(3).required(),
age: Joi.number().integer().min(0).required()
});
// Route
app.post('/user', (req, res) => {
const { error, value } = userSchema.validate(req.body);
if (error) {
return res.status(400).json({ error: error.details[0].message });
}
res.send(`User ${value.name} is ${value.age} years old`);
});
app.listen(3000, () => console.log('Server running on port 3000'));

πŸ§ͺ Example Requests

βœ… Valid Input
POST /user
{
"name": "Alice",
"age": 30
}

Response: User Alice is 30 years old

❌ Invalid Input
POST /user
{
"name": "A",
"age": "not-a-number"
}

Response: 400 Bad Request β€” "name" length must be at least 3 characters long

1.3 πŸ’‘ Validating req.params, req.query, etc.

You can also validate route parameters and query strings:

app.get('/search', (req, res) => {
const schema = Joi.object({
q: Joi.string().required(),
page: Joi.number().integer().min(1).default(1)
});
const { error, value } = schema.validate(req.query);
if (error) return res.status(400).send(error.details[0].message);
res.send(`Searching for ${value.q} on page ${value.page}`);
});

1.4 🧱 Middleware-based Validation

To avoid repeating validation code in every route, use a reusable middleware function:

function validateBody(schema) {
return (req, res, next) => {
const { error } = schema.validate(req.body);
if (error) return res.status(400).send(error.details[0].message);
next();
};
}
// Usage
app.post('/register', validateBody(Joi.object({
email: Joi.string().email().required(),
password: Joi.string().min(6).required()
})), (req, res) => {
res.send('User registered!');
});

πŸ›  Extra Features

  • .required() – field must be provided
  • .min(n) / .max(n) – value or string length
  • .email() – must be a valid email
  • .pattern(/regex/) – match regex
  • .default() – use default value if missing

1.5 πŸ“¦ Summary

FeatureCode Example
Schema definitionJoi.object({...})
Validationschema.validate(data)
Error handlingerror.details[0].message
MiddlewarevalidateBody(schema)
Query validationschema.validate(req.query)
Param validationschema.validate(req.params)