What is Middleware in Express and How It Works
Every Express beginner eventually reaches this moment:
You open some backend project and suddenly see this mysterious thing everywhere:
```js id="a72ks1"
app.use()
Then somebody says:
> “Oh that’s middleware.”
And beginners immediately pretend they understood.
Meanwhile internally:
> “What even is this creature?”
Because middleware sounds complicated.
But the reality is surprisingly simple.
Middleware is basically:
> a checkpoint system between request and response.
That’s it.
In this article, we will understand:
* what middleware actually is
* where it sits in Express
* how request flow works
* execution order
* role of `next()`
* types of middleware
* real-world examples like:
* logging
* authentication
* validation
And no, we are not diving into Express internals deep enough to summon ancient backend demons.
---
# First Understand How Request Flow Works
When a user sends request:
```text id="b81ms2"
Browser → Server
the request does not magically teleport to route handler.
Express processes it step by step.
Think of it like airport security.
Before boarding:
- ID check
- baggage check
- security check
- ticket verification
Only then:
you reach your gate.
Middleware works similarly.
What Is Middleware?
Middleware is:
a function that runs between request and response.
It gets access to:
- request object (
req) - response object (
res) - next function (
next)
Example:
```js id="c92ps1"
function middleware(req, res, next) {
console.log("Middleware running");
next();
}
This function executes before final response is sent.
---
# Middleware Position in Request Lifecycle
```text id="d73ks2"
Client Request
↓
Middleware
↓
Middleware
↓
Route Handler
↓
Response
This chain is called:
middleware pipeline
Request Pipeline Analogy
Imagine a restaurant.
Customer places order.
Before food reaches table:
- waiter checks order
- kitchen prepares food
- manager verifies bill
- staff serves plate
Many checkpoints exist before final output.
Middleware works the same way.
Why Middleware Exists
Middleware helps:
- organize logic
- reuse functionality
- separate responsibilities
Instead of writing:
- authentication
- logging
- validation
inside every route repeatedly.
Without middleware,
backend code becomes:
copy-paste Olympics.
Basic Middleware Example
```js id="e84js1"
const express = require("express");
const app = express();
function logger(req, res, next) {
console.log("Request received");
next();
}
app.use(logger);
app.get("/", (req, res) => {
res.send("Homepage");
});
app.listen(3000);
---
# What Happens Here?
When request comes:
```text id="f75ls1"
GET /
Flow becomes:
```text id="g66kd2"
Request
↓
logger middleware
↓
Route Handler
↓
Response
---
# Understanding `next()` Function
This is the most important middleware concept.
```js id="h57ps2"
next()
means:
“Move to the next middleware or route.”
Without next(),
request gets stuck forever.
Like customer support calls placed on eternal hold.
Example Without next()
```js id="i48ms1"
function middleware(req, res, next) {
console.log("Blocked");
}
Problem:
* request never reaches route
* browser keeps loading
Because middleware stopped the pipeline.
---
# Middleware Execution Sequence
Multiple middleware run in order.
Example:
```js id="j39ks2"
app.use((req, res, next) => {
console.log("Middleware 1");
next();
});
app.use((req, res, next) => {
console.log("Middleware 2");
next();
});
app.get("/", (req, res) => {
console.log("Route Handler");
res.send("Done");
});
Output:
```text id="k20jd1"
Middleware 1
Middleware 2
Route Handler
Execution order matters a lot.
---
# Middleware Execution Flow
```text id="l11ps2"
Request
↓
Middleware 1
↓
Middleware 2
↓
Middleware 3
↓
Route Handler
↓
Response
This is Express middleware chaining.
Types of Middleware in Express
Express mainly has:
- Application-level middleware
- Router-level middleware
- Built-in middleware
Let’s understand them one by one.
1. Application-Level Middleware
Applied to entire app.
Example:
```js id="m02ks1"
app.use((req, res, next) => {
console.log("Runs for every request");
next();
});
This runs for:
* `/`
* `/about`
* `/login`
* every route
Useful for:
* logging
* authentication
* request parsing
---
# Route-Specific Middleware
You can also apply middleware only to certain routes.
Example:
```js id="n93ms2"
app.get(
"/profile",
authMiddleware,
(req, res) => {
res.send("Profile Page");
}
);
Here:
- middleware runs only for
/profile
2. Router-Level Middleware
Express allows separate routers.
Example:
```js id="o84ps1"
const router = express.Router();
Middleware can be attached specifically to router.
Example:
```js id="p75ks2"
router.use((req, res, next) => {
console.log("Router Middleware");
next();
});
Useful for:
- modular backend structure
- large applications
Real-World Router Example
Imagine:
```text id="q66jd1"
/admin
All admin routes may require:
* authentication
* admin permission
Instead of repeating middleware everywhere,
router-level middleware handles all of them together.
---
# 3. Built-In Middleware
Express already provides some middleware.
Most common:
```js id="r57ms2"
express.json()
Used for:
parsing JSON request body
Example:
```js id="s48ks1"
app.use(express.json());
Without this,
`req.body` will be undefined for JSON requests.
And debugging that for 40 minutes is basically Express beginner tradition.
---
# Another Built-In Middleware
```js id="t39ps2"
express.static()
Used for serving:
- images
- CSS
- JavaScript files
Example:
```js id="u20ms1"
app.use(express.static("public"));
---
# Real-World Middleware Examples
Now let’s see actual practical use cases.
---
# 1. Logging Middleware
Tracks requests.
Example:
```js id="v11ks2"
function logger(req, res, next) {
console.log(`${req.method} ${req.url}`);
next();
}
Output:
```text id="w02jd1"
GET /
POST /login
GET /profile
Useful for:
* debugging
* monitoring traffic
* tracking API usage
---
# 2. Authentication Middleware
Protects private routes.
Example:
```js id="x93ms2"
function auth(req, res, next) {
const token = req.headers.authorization;
if (!token) {
return res.send("Access Denied");
}
next();
}
Flow:
```text id="y84ks1"
Request
↓
Check Token
↓
Valid?
↓ ↓
Yes No
↓ ↓
Next Reject
---
# 3. Request Validation Middleware
Checks incoming data.
Example:
```js id="z75ps2"
function validate(req, res, next) {
const { username } = req.body;
if (!username) {
return res.send("Username Required");
}
next();
}
Prevents bad data from entering application.
Combining Multiple Middleware
Example:
```js id="a66ms1"
app.post(
"/dashboard",
logger,
auth,
validate,
(req, res) => {
res.send("Welcome");
}
);
Execution order:
```text id="b57ks2"
Request
↓
Logger
↓
Authentication
↓
Validation
↓
Route Handler
↓
Response
Very clean structure.
Why Middleware Makes Express Powerful
Middleware allows:
- reusable code
- modular architecture
- cleaner backend structure
Instead of giant messy route handlers doing everything.
Without middleware,
large applications become:
giant spaghetti code disasters.
Important Middleware Rule
Order matters.
Example:
```js id="c48ps1"
app.use(express.json());
must come before routes using `req.body`.
Wrong order:
```js id="d39ms2"
app.post("/login", (req, res) => {
console.log(req.body);
});
app.use(express.json());
Result:
req.body becomes undefined.
Because middleware executed too late.
Common Beginner Mistakes
Forgetting next()
Result:
request hangs forever.
Sending Multiple Responses
Bad example:
```js id="e20ks1"
res.send("Hello");
next();
Can create errors because response already ended.
---
# Wrong Middleware Order
Execution sequence matters heavily in Express.
---
# Middleware Is Not Only for Authentication
Beginners often think:
> middleware = auth only
No.
Middleware can:
* modify requests
* log data
* validate forms
* parse JSON
* handle errors
* compress responses
It is basically:
> backend traffic control.
---
# Simple Middleware Mental Model
Think of middleware as:
# security checkpoints for requests
Each middleware decides:
* continue
* modify request
* block request
* send response
That’s the entire concept.
---
# Quick Revision
## Middleware Is:
* function between request and response
* part of request pipeline
---
## Middleware Receives:
```js id="f11ms2"
(req, res, next)
next() Means:
```text id="g02jd1"
Move to next middleware
---
## Types of Middleware:
* Application-level
* Router-level
* Built-in
---
## Common Uses:
* logging
* authentication
* validation
* parsing JSON
---
# Final Thoughts
Middleware is one of the reasons Express became so successful.
Because instead of writing massive unreadable route handlers,
Express allows backend logic to flow step by step like an organized pipeline.
And once middleware finally clicks in your brain,
you suddenly understand:
* authentication systems
* logging systems
* validation layers
* API architecture
much more clearly.
At its core,
middleware is simply:
> “Something that happens before the final response.”
That’s the big scary concept.
Just a checkpoint system for requests.
Top comments (0)