Script Valley
REST API Development: Complete Course from Beginner to Production
Building REST APIs with Express.jsLesson 3.3

Middleware in Express: Validation, Logging, and Error Handling

middleware concept, middleware stack, express middleware, request validation, Joi validation, morgan logging, error handling middleware, next function

Middleware in Express: Validation, Logging, and Error Handling

Middleware is the backbone of Express.js applications. A middleware function is a function that has access to the request, response, and the next middleware in the pipeline. Understanding the middleware stack is essential for building clean, maintainable REST APIs.

DiagramExpress Middleware Pipeline

IMAGE PROMPT (replace this block with your generated image):

Flat horizontal pipeline diagram on white background. Title: Express.js Middleware Pipeline. One HTTP Request box on the far left (browser icon, labeled Incoming Request). A horizontal pipeline of six sequential boxes connected by right-pointing arrows. Box 1: Logger (Morgan) — clock icon, light gray fill. Box 2: Body Parser (express.json) — curly brace icon, light gray fill. Box 3: Auth Check (JWT verify) — lock icon, fill light #3A5EFF (#e8ecff). Box 4: Validation (Joi) — checkmark icon, light green fill. Box 5: Route Handler — function icon, fill #3A5EFF with white text. Box 6: Error Handler — warning icon, light red fill. Each box labeled with the middleware name above and the npm package name below in small gray text. A dashed downward-branching arrow from Box 3 (Auth Check) labeled 401 if invalid token. A dashed downward-branching arrow from Box 4 (Validation) labeled 422 if invalid input. Final right side: HTTP Response box (labeled JSON Response). All main arrows in #3A5EFF, error branches in red #ef4444. White background.

How Middleware Works

Middleware functions execute in the order they are registered with app.use(). Each middleware can modify the request or response, end the request-response cycle, or call next() to pass control to the next middleware. If a middleware does not call next() and does not send a response, the request will hang.

Request Validation with Joi

npm install joi
const Joi = require('joi');

const userSchema = Joi.object({
  name: Joi.string().min(2).max(50).required(),
  email: Joi.string().email().required(),
  role: Joi.string().valid('user', 'admin').default('user')
});

const validateUser = (req, res, next) => {
  const { error } = userSchema.validate(req.body, { abortEarly: false });
  if (error) {
    return res.status(422).json({
      success: false,
      error: {
        code: 'VALIDATION_ERROR',
        details: error.details.map(d => ({
          field: d.path.join('.'),
          message: d.message
        }))
      }
    });
  }
  next();
};

Request Logging with Morgan

npm install morgan
app.use(morgan('dev'));

Morgan logs every request: method, URL, status code, response time, and content length. Use 'combined' format in production for Apache-style logs that include IP addresses.

Centralized Error Handling

Express has a special four-parameter error handling middleware signature. Register it last, after all routes:

app.use((err, req, res, next) => {
  console.error(err.stack);
  const statusCode = err.statusCode || 500;
  res.status(statusCode).json({
    success: false,
    error: {
      code: err.code || 'INTERNAL_ERROR',
      message: process.env.NODE_ENV === 'production'
        ? 'An unexpected error occurred'
        : err.message
    }
  });
});

Up next

Project Structure: Scalable Architecture for REST APIs

Sign in to track progress