Node.js8 min read
Express Middleware Explained
Understand Express middleware - functions that process requests. Learn to create and use middleware effectively.
Sarah Chen
December 19, 2025
0.0k0
Express Middleware Explained
Middleware = functions that run between request and response. They're Express's superpower.
What is Middleware?
function middleware(req, res, next) {
// Do something with request
console.log('Request received');
// Pass to next middleware
next();
}
The Request Flow
Request → Middleware 1 → Middleware 2 → Route Handler → Response
Using Middleware
const express = require('express');
const app = express();
// Apply to ALL routes
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`);
next();
});
// Apply to specific path
app.use('/api', (req, res, next) => {
console.log('API request');
next();
});
// Routes
app.get('/', (req, res) => res.send('Home'));
Built-in Middleware
// Parse JSON bodies
app.use(express.json());
// Parse URL-encoded bodies (form data)
app.use(express.urlencoded({ extended: true }));
// Serve static files
app.use(express.static('public'));
Creating Custom Middleware
Logger:
function logger(req, res, next) {
const timestamp = new Date().toISOString();
console.log(`[${timestamp}] ${req.method} ${req.url}`);
next();
}
app.use(logger);
Request Timer:
function timer(req, res, next) {
req.startTime = Date.now();
res.on('finish', () => {
const duration = Date.now() - req.startTime;
console.log(`Request took ${duration}ms`);
});
next();
}
app.use(timer);
Auth Check:
function requireAuth(req, res, next) {
const token = req.headers.authorization;
if (!token) {
return res.status(401).json({ error: 'No token provided' });
}
// Verify token...
req.user = { id: 1, name: 'Alice' };
next();
}
// Use on specific routes
app.get('/api/profile', requireAuth, (req, res) => {
res.json(req.user);
});
Order Matters!
// ✅ Correct - body parser before routes
app.use(express.json());
app.post('/data', (req, res) => {
console.log(req.body); // Works!
});
// ❌ Wrong - body parser after route
app.post('/data', (req, res) => {
console.log(req.body); // undefined!
});
app.use(express.json());
Error Handling Middleware
// Regular middleware has 3 params
// Error middleware has 4 (err first)
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: 'Something broke!' });
});
// Trigger error
app.get('/error', (req, res, next) => {
next(new Error('Oops!'));
});
Third-Party Middleware
const cors = require('cors');
const helmet = require('helmet');
const morgan = require('morgan');
app.use(cors()); // Enable CORS
app.use(helmet()); // Security headers
app.use(morgan('dev')); // Request logging
Middleware Factory
function rateLimit(maxRequests, windowMs) {
const requests = new Map();
return (req, res, next) => {
const ip = req.ip;
const now = Date.now();
if (!requests.has(ip)) {
requests.set(ip, []);
}
const userRequests = requests.get(ip)
.filter(time => now - time < windowMs);
if (userRequests.length >= maxRequests) {
return res.status(429).json({ error: 'Too many requests' });
}
userRequests.push(now);
requests.set(ip, userRequests);
next();
};
}
// 100 requests per minute
app.use(rateLimit(100, 60000));
Key Takeaway
Middleware processes requests in order. Always call next() to continue the chain. Use built-in middleware for JSON/forms, third-party for logging/security, and custom for app-specific logic. Put them before your routes!
#Node.js#Express#Middleware#Intermediate