← Back to all snippets
JAVASCRIPT

Implement Schema-Based Server-Side Input Validation with Joi in Node.js

Enhance API security by implementing comprehensive server-side input validation using the Joi schema validation library in Node.js, ensuring data integrity and preventing malicious payloads.

const express = require('express');
const Joi = require('joi'); // Joi is a powerful schema description and validation library
const bodyParser = require('body-parser');

const app = express();
const port = 3000;

// Middleware to parse JSON request bodies
app.use(bodyParser.json());

// Define a Joi schema for user registration data
const userSchema = Joi.object({
  username: Joi.string().alphanum().min(3).max(30).required(),
  email: Joi.string().email({ tlds: { allow: ['com', 'net', 'org'] } }).required(),
  password: Joi.string().pattern(new RegExp('^[a-zA-Z0-9]{3,30}$')).required(), // Example: Alphanumeric 3-30 chars
  age: Joi.number().integer().min(18).max(120).optional(),
  role: Joi.string().valid('user', 'admin').default('user'),
});

// Validation middleware function
const validate = (schema) => (req, res, next) => {
  const { error } = schema.validate(req.body, { abortEarly: false }); // abortEarly: false to get all errors
  if (error) {
    const errors = error.details.map(err => err.message);
    return res.status(400).json({ errors: errors });
  }
  next();
};

// Route for user registration with validation
app.post('/register', validate(userSchema), (req, res) => {
  // If we reach here, the request body is valid
  const newUser = req.body;
  console.log('Validated User Data:', newUser);
  // In a real application, you would save newUser to a database
  res.status(201).json({ message: 'User registered successfully!', user: newUser });
});

// Example of another schema for updating user details
const updateUserSchema = Joi.object({
    email: Joi.string().email({ tlds: { allow: ['com', 'net', 'org'] } }).optional(),
    age: Joi.number().integer().min(18).max(120).optional(),
    role: Joi.string().valid('user', 'admin').optional(),
}).min(1); // At least one field must be provided for update

app.put('/users/:id', validate(updateUserSchema), (req, res) => {
    const userId = req.params.id;
    const updatedData = req.body;
    console.log(`Updating user ${userId} with data:`, updatedData);
    res.json({ message: `User ${userId} updated successfully!`, updated: updatedData });
});

app.get('/', (req, res) => {
  res.send('Welcome to the Joi validation example!');
});

app.listen(port, () => {
  console.log(`Server running on http://localhost:${port}`);
  console.log('Try POSTing to /register with valid and invalid JSON data.');
  console.log('e.g., {"username": "john_doe", "email": "[email protected]", "password": "MySecurePassword123", "age": 30}');
});

/*
Example invalid request (POST to /register):
{
  "username": "jo", // Too short
  "email": "invalid-email", // Invalid format
  "password": "123", // Too short
  "age": 10 // Too young
}
*/
How it works: This Node.js Express snippet demonstrates robust server-side input validation using the `Joi` library. It defines clear schemas for expected data structures (e.g., user registration) and then uses a generic `validate` middleware to apply these schemas to incoming request bodies. Joi allows defining strict rules for data types, formats, lengths, patterns, and allowed values. This process ensures that only well-formed and legitimate data enters your application's logic and database, preventing many common security vulnerabilities and errors arising from malformed or malicious inputs.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs