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

INTRODUCTION:

Imagine you enter an airport.
Before boarding your flight, you pass through multiple checkpoints:

  • Security check πŸ›‚

  • Identity verification πŸͺͺ

  • Baggage scanning πŸŽ’

Only after clearing all these do you reach your gate.

In Express.js, middleware works exactly like these checkpoints. Every request passes through a series of checks before reaching the final response.

In this blog, we will demystify the core of Express.js by exploring how middleware functions act as the essential glue between an incoming request and the final response.

What middleware is in Express?

Middleware functions are the building blocks of Express. These functions have access to the Request object (req), the Response object (res), and the next middleware function in the application’s request-response cycle.

Middleware in Express is a function that has access to:

  • req (request object)

  • res (response object)

  • next (function to pass control)

It executes between receiving a request and sending a response.

The Request Pipeline

Express operates as a pipeline. When a request enters, it does not jump straight to the final logic. Instead, it travels through a series of "checkpoints." Each checkpoint can inspect the request, modify the data, or terminate the cycle entirely if certain conditions aren't met.

function middleware(req, res, next) {
  console.log("Middleware executed");
  next(); // pass control
}

Where Middleware Sits in the Lifecycle

Middleware occupies the space between the moment the server receives a request and the moment the route handler sends back a response.

Execution Flow:

[Client] 
   |
  β–Ό
[Request] ----> [Middleware A] ----> [Middleware B] ----> [Route Handler]
                     (Auth)           (Validation)          (Controller)
                                                                 |
[Response] <-----------------------------------------------------+

Middleware acts as a processing layer before the final logic runs.

Types of Middleware

Application-Level Middleware

Bound to the app instance using app.use(). These run for every incoming request across the entire application.

Applied to the whole app

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

βœ” Runs for every request

Router-Level Middleware

Bound to an instance of express.Router(). This is used to scope middleware to specific modules, such as an /api/auth group.

Applied to specific routes

const router = express.Router();

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

βœ” Runs only for routes inside that router

Built-in Middleware

Functions provided natively by Express, such as express.json() for parsing incoming JSON payloads.

Provided by Express

Examples:

  • express.json() β†’ parses JSON

  • express.static() β†’ serves static files

app.use(express.json());

Execution Order and the next() Function

Express executes middleware in the exact order they are defined in the code. This top-to-bottom sequence is vital for logic that depends on previous steps (like needing a body parser before validating the data).

The next() function is the manual trigger that moves the request to the next function in the stack. If next() is not called and a response is not sent, the request will hang.

app.use((req, res, next) => {
  console.log("First");
  next();// Pass control to the next middleware
});

app.use((req, res, next) => {
  console.log("Processing request..."); // Pass control to the next middleware
  next();
});

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

Real-World Examples

Logging Middleware

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

βœ” Tracks all incoming requests

Authentication Middleware

function auth(req, res, next) {
  if (req.headers.authorization) {
    next();
  } else {
    res.status(401).send("Unauthorized");
  }
}

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

βœ” Protects routes

Request Validation Middleware

function validate(req, res, next) {
  if (req.body.name) {
    next();
  } else {
    res.status(400).send("Name required");
  }
}

app.post("/user", validate, (req, res) => {
  res.send("User created");
});

βœ” Ensures correct data

Full Flow Diagram

Client Request
     ↓
[ Logging Middleware ]
     ↓
[ Authentication Middleware ]
     ↓
[ Validation Middleware ]
     ↓
[ Route Handler ]
     ↓
Response Sent

Key Takeaways

  • Middleware = checkpoint between request and response

  • It works in a pipeline (sequence)

  • Types:

    • Application-level β†’ global

    • Router-level β†’ specific routes

    • Built-in β†’ provided by Express

  • next() is critical to continue execution

  • Order matters β†’ top to bottom execution

  • Used for:

    • Logging

    • Authentication

    • Validation

In closing

I hope that you’ve found this blog on β€œWhat is Middleware in Express and How It Works” helpful...!

That's all for today! 😁 You reached the end of the article 😍.

Want more..?

I write articles on princekumar-engineer.hashnode.dev, and also post development-related content on the following platforms:

Node.js

Part 10 of 15

A complete beginner-to-advanced guide to learning Node.js and Express.js, covering core concepts, asynchronous programming, REST APIs, middleware, file handling, and authentication techniques.

Up next

URL Parameters vs Query Strings in Express.js

INTRODUCTION: Navigating a dynamic Express.js application requires a solid grasp of how data travels through the URL. Whether you are identifying a specific user or filtering a list of products, choos