Skip to main content
Practice Problems

What is middleware in Express.js and how does it work?

Middleware in Express.js

Middleware are functions that have access to the request object (req), response object (res), and the next middleware function (next). They sit in the middle of the request-response cycle.


Middleware Signature

js
function myMiddleware(req, res, next) { // do something next(); // call next middleware }

If you don't call next(), the request cycle stops here.


The Middleware Pipeline

Request → MW1 → MW2 → MW3 → Route Handler → Response

Each middleware can:

  • Execute any code
  • Modify req and res
  • End the request-response cycle
  • Call next() to pass control to the next middleware

Types of Middleware

1. Application-level

js
const express = require('express'); const app = express(); // Runs for every request app.use((req, res, next) => { console.log(`${req.method} ${req.path}`); next(); });

2. Route-level

js
// Only runs for this route app.get('/users', authenticate, (req, res) => { res.json({ users: [] }); });

3. Error-handling (4 parameters!)

js
app.use((err, req, res, next) => { console.error(err.stack); res.status(500).json({ error: err.message }); });

4. Built-in middleware

js
app.use(express.json()); // parse JSON body app.use(express.urlencoded()); // parse URL-encoded body app.use(express.static('public')); // serve static files

5. Third-party middleware

js
const cors = require('cors'); const helmet = require('helmet'); const morgan = require('morgan'); app.use(cors()); // enable CORS app.use(helmet()); // security headers app.use(morgan('dev')); // logging

Real-World Example

js
const express = require('express'); const app = express(); // 1. Parse JSON app.use(express.json()); // 2. Logging app.use((req, res, next) => { console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`); next(); }); // 3. Auth middleware function authenticate(req, res, next) { const token = req.headers.authorization?.split(' ')[1]; if (!token) return res.status(401).json({ error: 'Unauthorized' }); try { req.user = verifyJWT(token); next(); } catch { res.status(401).json({ error: 'Invalid token' }); } } // 4. Protected route app.get('/profile', authenticate, (req, res) => { res.json({ user: req.user }); }); // 5. Error handler (must be last!) app.use((err, req, res, next) => { res.status(500).json({ error: err.message }); }); app.listen(3000);

next('route') vs next(err)

js
next() // proceed to next middleware next('route') // skip remaining middleware, go to next route next(err) // skip to error handler

Summary

Middleware is the building block of Express apps. The request flows through each middleware in the order they are registered. Use middleware for cross-cutting concerns: logging, authentication, validation, rate limiting, error handling, and more.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.

Finished reading?
Practice Problems