Skip to main content

Command Palette

Search for a command to run...

What is Middleware in Express and How It Works

Updated
4 min read
What is Middleware in Express and How It Works

1. What is Middleware?

At its core, middleware is a function that has access to the Request object (req), the Response object (res), and the next function in the application’s request-response cycle.

Think of middleware as a checkpoint. Every time a request is made to your server, it doesn't just jump straight to the data; it passes through these checkpoints. Each one can:

  • Execute any code.

  • Make changes to the request and the response objects.

  • End the request-response cycle (by sending a response).

  • Call the next middleware in the stack.

2. The Request Lifecycle & Pipeline

Middleware sits squarely between the raw request and the final route handler.

The Pipeline Analogy

Imagine a physical water pipeline. Water (the request) enters at one end. Along the pipe, there are various filters (middleware):

  1. Filter 1 (Logging): Records that water is flowing.

  2. Filter 2 (Auth): Checks if the water has the right "clearance" to pass.

  3. Filter 3 (Validation): Ensures the water isn't carrying debris (bad data).

If any filter finds an issue, it can shut the valve (send an error response) and stop the flow. If everything is fine, it passes the water to the next section using the next() function.

3. The Core Types of Middleware

1.Application-level Middleware

These are bound to an instance of the app object using app.use(). They run for every request made to the server (unless restricted to a specific path).

const app = express();

app.use((req, res, next) => {
  console.log("Request received");
  next();
});

2. Router-level Middleware

This works exactly like application-level middleware, except it is bound to an instance of express.Router(). This is great for modularizing your code (e.g., all /api/v1 routes requiring an API key).

const router = require('express').Router();

router.use((req, res, next) => {
  console.log("Router-level middleware");
  next();
});

3. Built-in Middleware

Express comes with a few standard pieces of middleware so you don't have to reinvent the wheel:

  • express.json() parses incoming requests with JSON payloads.

  • express.static() serves static assets like HTML files and images.

app.use(express.json());

4.Execution Order

Middleware is executed sequentially. The order in which you define them in your code via app.use() is the order in which they will execute.

👉 Middleware runs in the order they are defined

app.use(middleware1);
app.use(middleware2);
app.get('/', handler);

Flow:

Request → middleware1 → middleware2 → handler

⚠️ If one middleware doesn't call next(), the request gets stuck.

5.The Secret Sauce: The next() Function

The next() function is the most critical part of middleware. It is a function that, when invoked, executes the middleware succeeding the current one.

Warning: If you don’t call next() and you don’t send a response back to the client (like res.send()), your request will be left "hanging," and the client will eventually time out.

➡️ “Move to the next middleware in the chain”

app.use((req, res, next) => {
  console.log("Step 1");
  next();
});

Real-World Examples

1. Logging

Every professional app needs to know who is visiting. A simple logger records the HTTP method and the URL requested.

app.use((req, res, next) => {
  console.log(`\({req.method} request to \){req.url}`);
  next(); 
});

2. Authentication

Before showing a user their profile, you need to verify who they are.

const checkAuth = (req, res, next) => {
  if (req.headers.authorization === 'secret-token') {
    next(); // Authenticated! Move to the profile route.
  } else {
    res.status(403).send('Unauthorized'); // Stop the flow here.
  }
};

3. Request Validation

Ensuring the data sent by the user is clean before it touches your database.

app.post('/user', (req, res, next) => {
  if (!req.body.email) {
    return res.status(400).send('Email is required');
  }
  next();
});

JavaScript form basic concepts to Advance

Part 17 of 17

Master JavaScript from the ground up. This series takes you on a complete journey from fundamental syntax and variables to advanced asynchronous patterns, closures, and performance optimization. Whether you are a beginner writing your first line of code or an intermediate developer looking to bridge the gap to seniority, these guides provide deep dives, practical examples, and modern best practices for the 2026 ecosystem.

Start from the beginning

JavaScript Modules: Import and Export Explained

Imagine building a Lego castle where every brick is permanently glued to the next. If you want to change the color of the tower, you have to break the whole thing down. That is what coding without Mod