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.

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

Middleware in Express: Validation, Logging, and Error Handling โ€” Building REST APIs with Express.js โ€” REST API Development: Complete Course from Beginner to Production โ€” Script Valley โ€” Script Valley