Express Joi Middleware

raw JSON →
1.0.0 verified Thu Apr 23 auth: no javascript

express-joi-middleware is an Express.js middleware designed to integrate Hapi.js's Joi validation library seamlessly into Express applications. Currently at its first stable release, version 1.0.0, this package provides robust request body, query, parameters, and headers validation against user-defined Joi schemas. Its key differentiators include extensive customization options, such as the ability to supply a specific Joi instance (useful for managing Joi versions or custom extensions), fine-grained control over error response handling (either automatically sending a 400 Bad Request or `next`ing the Joi error for custom handling), and the choice to override the `req.body` or create a new `req.validated` key with the processed data. The project is new, so a specific release cadence has not yet been established, but it focuses on providing a flexible and configurable validation layer.

error ReferenceError: Joi is not defined
cause The Joi object was used to define a schema (e.g., `Joi.string()`) without being explicitly imported into the file.
fix
Add const Joi = require('joi'); at the top of the file where your Joi schemas are defined.
error TypeError: app.use() requires a middleware function but got a Object
cause The `expressJoiMiddleware` function was called incorrectly or not at all. It expects two arguments: a schema object and an optional options object.
fix
Ensure you are calling expressJoiMiddleware(schemaObject, optionsObject) to return the middleware function, e.g., app.post('/path', expressJoiMiddleware(mySchema), (req, res) => ...);.
error Error: Invalid IP address: 127.0.0.1 (Joi error)
cause A Joi validation rule (e.g., `Joi.ip()`) failed for an input field.
fix
Review the Joi schema definition and the input data being sent to ensure they match the expected validation rules. The error message from Joi often provides specific details on what failed.
gotcha The quickstart example in the README omits the explicit `require('joi')` statement, which is essential for defining Joi schemas. Without it, you will encounter runtime errors indicating `Joi is not defined`.
fix Always include `const Joi = require('joi');` at the top of your file when defining Joi schemas for `express-joi-middleware`.
gotcha By default (`wantResponse: false`), `express-joi-middleware` will `next` Joi validation errors to the next middleware. If you do not have a custom error-handling middleware set up to catch `err.isJoi` errors, these errors will propagate and potentially crash your application or result in generic 500 errors.
fix Either set `wantResponse: true` in the middleware options for automatic 400 Bad Request responses, or implement an Express error-handling middleware (`app.use((err, req, res, next) => { ... })`) to specifically handle `err.isJoi` validation errors.
gotcha As of version 1.0.0, this package is exclusively CommonJS. Attempting to use ESM `import` statements will result in a runtime error.
fix Use `const expressJoiMiddleware = require('express-joi-middleware');` for importing the middleware.
npm install express-joi-middleware
yarn add express-joi-middleware
pnpm add express-joi-middleware

This quickstart demonstrates how to set up `express-joi-middleware` in an Express application to validate request bodies and path parameters using Joi schemas, including explicit Joi import and an error handling middleware.

const express = require('express');
const bodyParser = require('body-parser');
const Joi = require('joi'); // Crucial: Joi must be imported by the user
const expressJoiMiddleware = require('express-joi-middleware');

const app = express();

app.use(bodyParser.json());

const userSchema = {
    body: {
        id: Joi.string().guid({ version: 'uuidv4' }).required(),
        name: Joi.string().min(3).max(30).required(),
        email: Joi.string().email().required()
    },
    params: {
        userId: Joi.string().guid({ version: 'uuidv4' }).required()
    }
};

const options = {
    wantResponse: true // Middleware sends 400 Bad Request automatically
};

// Example: Validating a POST request body
app.post('/users', expressJoiMiddleware(userSchema, options), (req, res) => {
    // req.validated will contain the validated and transformed body/query/params
    res.status(201).json({ message: 'User created successfully', data: req.validated });
});

// Example: Validating a GET request with path parameters
app.get('/users/:userId', expressJoiMiddleware(userSchema, options), (req, res) => {
    res.json({ message: `Fetching user ${req.validated.userId}`, user: { id: req.validated.userId, name: 'Example User' } });
});

// Custom error handler for Joi errors if wantResponse is false or for other errors
app.use((err, req, res, next) => {
    if (err.isJoi) {
        console.error('Joi validation error:', err.details);
        return res.status(400).json(err.details);
    }
    console.error('Internal server error:', err);
    res.status(500).send('Internal Server Error');
});

app.listen(8080, () => {
    console.log('Server listening on http://localhost:8080');
});