Skip to main content

Command Palette

Search for a command to run...

What is Middleware in Express and How It Works

Published
5 min read
D
Turning confusing web concepts into simple, real-world explanations. Writing about JavaScript, Node.js, and how things actually work.

When building applications with Express, requests usually do not go directly from:

Client → Route Handler → Response

Instead, requests often pass through multiple intermediate functions first.

Examples:

  • logging requests

  • checking authentication

  • validating request data

  • parsing JSON

  • handling errors

These intermediate functions are called:

Middleware

Middleware is one of the most important concepts in Express because almost everything in Express works through middleware internally.

Let’s understand how it actually works.


What Is Middleware in Express?

Middleware is a function that runs:

  • between receiving a request

  • and sending a response

It acts like a checkpoint in the request lifecycle.

Example mental model:

Request
↓
Middleware
↓
Route Handler
↓
Response

Middleware can:

  • modify requests

  • modify responses

  • stop requests

  • continue requests

  • execute additional logic


Middleware as a Request Pipeline

Think of middleware like security checkpoints at an airport.

A request enters the system and passes through multiple checkpoints:

  • logging checkpoint

  • authentication checkpoint

  • validation checkpoint

Each middleware decides:

  • continue request

  • reject request

  • modify request

Only after passing all required checkpoints does the request reach the final route handler.


Basic Middleware Example

Example:

const middleware = (req, res, next) => {
  console.log("Middleware Running");

  next();
};

Understanding Middleware Parameters

Middleware functions usually receive:

(req, res, next)
Parameter Meaning
req Incoming request
res Outgoing response
next Pass control to next middleware

Where Middleware Sits in the Request Lifecycle

Example flow:

Client sends request
↓
Middleware executes
↓
Another middleware executes
↓
Route handler executes
↓
Response sent back

Requests move through a middleware chain.


Role of next() Function

next() is extremely important.

It tells Express:

“Move to the next middleware or route handler.”

Example:

const logger = (req, res, next) => {
  console.log("Request Received");

  next();
};

Without next():

  • request gets stuck

  • route handler never runs


What Happens Without next()?

Example:

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

Here:

  • no response sent

  • no next() called

The request hangs forever.

Because Express is waiting for the middleware chain to continue.


Using Middleware in Express

Example:

app.use((req, res, next) => {
  console.log("Middleware Executed");

  next();
});

app.use() registers middleware globally.

This means:

  • every request passes through it

Middleware Execution Order

Middleware executes in the exact order it is defined.

Example:

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

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

Request flow:

First
Second

Order matters a lot in Express applications.


Request Pipeline Example

Request
↓
Logger Middleware
↓
Authentication Middleware
↓
Validation Middleware
↓
Route Handler
↓
Response

Each middleware performs one responsibility.


Types of Middleware in Express

Express supports multiple middleware types.


1. Application-Level Middleware

Middleware attached directly to the Express app.

Example:

app.use((req, res, next) => {
  console.log("App Middleware");

  next();
});

Runs for matching requests across the application.


2. Router-Level Middleware

Middleware attached to specific routers.

Example:

router.use((req, res, next) => {
  console.log("Router Middleware");

  next();
});

Useful for grouping related routes.

Example:

  • admin routes

  • auth routes

  • API routes


3. Built-In Middleware

Express already provides built-in middleware.

Example:

app.use(express.json());

This middleware:

  • parses JSON request bodies

  • makes data available inside req.body

Without it:

  • JSON request data would not be parsed automatically

Real-World Middleware Examples

Middleware becomes powerful because it allows reusable request processing.


Example 1: Logging Middleware

app.use((req, res, next) => {
  console.log(req.method, req.url);

  next();
});

Purpose:

  • track incoming requests

  • debugging

  • monitoring traffic


Example 2: Authentication Middleware

const auth = (req, res, next) => {
  const token = req.headers.authorization;

  if (!token) {
    return res.status(401).send("Unauthorized");
  }

  next();
};

Purpose:

  • protect private routes

  • verify user identity


Example 3: Request Validation Middleware

const validate = (req, res, next) => {
  if (!req.body.email) {
    return res.status(400).send("Email Required");
  }

  next();
};

Purpose:

  • validate incoming request data

  • prevent invalid requests


Middleware Can Modify Requests

Middleware can add data to requests.

Example:

req.user = {
  id: 1
};

Now later middleware or routes can access:

req.user

This is commonly used in authentication systems.


Middleware Can End Requests Early

Middleware does not always continue execution.

Example:

if (!token) {
  return res.status(401).send("Unauthorized");
}

Sometimes middleware blocks requests completely.


Express Middleware Flow Example

app.use(logger);

app.get("/dashboard", auth, (req, res) => {
  res.send("Dashboard");
});

Flow:

Request
↓
Logger middleware
↓
Auth middleware
↓
Dashboard route
↓
Response

Why Middleware Is Powerful

Middleware helps:

  • separate concerns

  • reuse logic

  • keep routes cleaner

  • organize backend architecture

Instead of repeating logic everywhere, middleware centralizes functionality.


Simple Mental Model

Think of middleware like checkpoints on a highway.

Each checkpoint:

  • inspects request

  • modifies request

  • allows request forward

  • or blocks request completely


Middleware is the core mechanism behind Express request processing.

It sits between:

  • incoming request

  • final response

and allows applications to:

  • process requests step-by-step

  • organize reusable logic

  • control request flow cleanly

The key ideas are:

  • middleware runs in sequence

  • execution order matters

  • next() moves the pipeline forward