Skip to main content

Command Palette

Search for a command to run...

Express Middleware Explained: The Request Pipeline You Must Understand

Updated
4 min read
Express Middleware Explained: The Request Pipeline You Must Understand

Ever wondered how a request in Express.js doesn’t directly reach the route, but gets processed step by step?

That’s where middleware comes in.

It acts like a checkpoint between the request and response, helping manage tasks like logging, authentication, and validation in a structured way.

1. What is Middleware in Express?

Middleware in Express.js is a function that sits between the request and the response. Think of it as a checkpoint .

When a client sends a request to the server:

The request doesn’t directly reach the route handler. Instead, it passes through one or more middleware functions.

👉 Each middleware can:

  • Modify the request (req)

  • Modify the response (res)

  • End the request-response cycle

  • Or pass control to the next middleware

Middleware = Functions that process requests before they reach the final route handler.


2. Where Middleware Sits in the Request Lifecycle

Request Pipeline Analogy

Imagine a pipeline:

Client Request
      ↓
[ Middleware ]
      ↓
[ Middleware ]
      ↓
[ Route Handler ]
      ↓
Response Sent Back

Each middleware acts like a filter or processing unit.


3. Types of Middleware in Express

🔹 Application-Level Middleware

Attached to the app using app.use()

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

Runs for every request (unless restricted)


🔹 Router-Level Middleware

Used with express.Router()

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

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

Runs only for specific routes


🔹 Built-in Middleware

Provided by Express itself:

app.use(express.json());
app.use(express.urlencoded({ extended: true }));

Used for:

  • Parsing JSON

  • Parsing form data


4.Execution Order of Middleware

Middleware executes in the order they are defined.

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

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

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

Output:

First
Second

If you change the order Output changes.


Multiple Middleware Execution Chain

Request
  ↓
[ Middleware 1 ]
  ↓
[ Middleware 2 ]
  ↓
[ Middleware 3 ]
  ↓
[ Route Handler ]
  ↓
Response

This shows chain execution clearly


5. Role of next() Function

The next() function is the key to middleware flow.

🔹 What does next() do?

👉 It tells Express:

“Move to the next middleware in the pipeline”


Without next()

app.use((req, res, next) => {
  console.log("Stops here");
});
  • Request gets stuck (No response, no next middleware)

With next()

app.use((req, res, next) => {
  console.log("Continue");
  next();
});
  • Request moves forward

🔹 Middleware Function Structure

(req, res, next) => {
  // logic
  next();
}

👉 Parameters:

  • req → Request object

  • res → Response

  • object next → Function to pass control


Real-World Examples of Middleware

🔹 1. Logging Middleware

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

Tracking incoming requests


🔹 2. Authentication Middleware

app.use((req, res, next) => {
  const isLoggedIn = true;

  if (isLoggedIn) {
    next();
  } else {
    res.send("Unauthorized");
  }
});

Protects routes


🔹 3. Request Validation Middleware

app.post('/user', (req, res, next) => {
  if (!req.body.name) {
    return res.send("Name is required");
  }
  next();
});

Ensures correct data


Conclusion

Middleware follows a pipeline approach where each middleware processes the request step by step. The next() function ensures smooth flow by passing control to the next middleware. Overall, middleware makes applications more structured, maintainable, and efficient