Back to Interview PrepGet interview ready with AILearn each topic the way interviewers ask it, then answer like you would in the interview.
Course progress0/12 chapters · 0%

Chapter 4 of 13

~11 min

Middleware

Middleware is the concept that everything else in Express is built on: functions that sit in the request-handling pipeline, able to inspect or modify the request and response, and either end the cycle or pass control along to whatever comes next.

What Middleware Is

A middleware function is just a regular function with the signature (req, res, next). It receives the same req and res objects a route handler would, plus a third function, next, which hands control to the next middleware or route handler registered after it. Middleware can read or modify req and res, run any code (logging, authentication checks, parsing), and then either call next() to continue the pipeline or send a response itself to end it.

server.js
function requestLogger(req, res, next) {
  console.log(`${new Date().toISOString()} ${req.method} ${req.url}`);
  next(); // hand off control - without this, the request hangs forever
}

module.exports = requestLogger;
A minimal logging middleware

Registering Middleware with app.use()

app.use() registers middleware that runs for every request (or, given a path prefix, every request under that path), regardless of HTTP method. This is the standard way to apply something like logging, body parsing, or CORS headers across an entire app without repeating it in every route.

server.js
const express = require('express');
const app = express();

app.use((req, res, next) => {
  console.log(`Incoming: ${req.method} ${req.url}`);
  next();
});

// This middleware only runs for paths starting with /admin
app.use('/admin', (req, res, next) => {
  console.log('Admin area accessed');
  next();
});

app.get('/', (req, res) => res.send('Home'));
app.get('/admin/dashboard', (req, res) => res.send('Dashboard'));

The (req, res, next) Signature and Forgetting next()

Every non-error middleware function must eventually either call next() or send a response (via res.send/json/end/etc.). If a middleware does neither, the request simply hangs until the client times out, since Express has no way of knowing the middleware is "done" unless it is told so explicitly. This is one of the most common bugs when writing custom middleware, especially inside conditional branches where one path calls next() but another forgets to.

Execution Order Is Registration Order

Express runs middleware strictly in the order it was registered on the app (or router), which means middleware that needs to run first - like body parsing, or authentication - must be registered before the routes that depend on it. Middleware registered after a route that already sent a response simply never runs for that request.

server.js
function requireAuth(req, res, next) {
  if (!req.headers.authorization) {
    return res.status(401).json({ error: 'Missing Authorization header' });
  }
  next();
}

// requireAuth must be registered before the route it protects
app.use('/admin', requireAuth);
app.get('/admin/dashboard', (req, res) => res.send('Dashboard'));
Order matters: auth before the protected route

Coding challenge

Write a middleware function called timingLogger that records the start time when a request comes in, calls next(), and then - once the response finishes - logs how many milliseconds the request took, using the response’s "finish" event.

// Write your solution here

Answer every question below to mark this chapter as complete.

Quiz Yourself

Score: 0/4

1. What is the standard function signature of an Express middleware function?

2. What happens if a middleware function never calls next() and never sends a response?

3. If app.use() logging middleware is registered after all of the app’s routes, what is the practical effect?

4. What does passing a path as the first argument to app.use(path, middleware) do?

You're viewing a free lesson. Sign up free to track your progress and unlock the full course.Sign up freeSign in