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



