Express.js Middleware
Master Express.js middleware to handle requests, implement authentication, logging, error handling, and build modular applications.
Overview
Middleware functions are the backbone of Express.js applications. They have access to the request object, response object, and the next middleware function in the application's request-response cycle.
What is Middleware?
Middleware functions can execute code, modify request and response objects, end the request-response cycle, or call the next middleware in the stack.
Types of Middleware
Express supports several types of middleware: - **Application-level middleware**: Bound to the app object using app.use() or app.METHOD() - **Router-level middleware**: Works like application-level but is bound to an instance of express.Router() - **Error-handling middleware**: Takes four arguments (err, req, res, next) to handle errors - **Built-in middleware**: Express has built-in middleware like express.static, express.json, and express.urlencoded - **Third-party middleware**: Packages like cors, helmet, morgan for additional functionality
Middleware Execution Order
Middleware functions are executed sequentially in the order they are defined. This order is crucial for proper application behavior.
Creating Custom Middleware
You can create custom middleware for logging, authentication, validation, and more. The key is calling next() to pass control to the next middleware.
Code Examples
Basic Middleware
// Simple logging middleware
const logger = (req, res, next) => {
console.log(`${req.method} ${req.url} - ${new Date().toISOString()}`);
next(); // Pass control to next middleware
};
// Apply to all routes
app.use(logger);
// Apply to specific route
app.use('/api', logger);Authentication Middleware
const authenticate = (req, res, next) => {
const token = req.headers.authorization?.split(' ')[1];
if (!token) {
return res.status(401).json({ error: 'No token provided' });
}
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = decoded;
next();
} catch (error) {
res.status(401).json({ error: 'Invalid token' });
}
};
// Protect routes
app.get('/profile', authenticate, (req, res) => {
res.json({ user: req.user });
});Error Handling Middleware
// Error handling middleware (4 parameters)
const errorHandler = (err, req, res, next) => {
console.error(err.stack);
const statusCode = err.statusCode || 500;
const message = err.message || 'Internal Server Error';
res.status(statusCode).json({
error: {
message,
...(process.env.NODE_ENV === 'development' && { stack: err.stack })
}
});
};
// Must be defined after all other middleware and routes
app.use(errorHandler);Frequently Asked Questions
Why is the order of middleware important?
What happens if I forget to call next()?
How do I pass data between middleware functions?
Need expert help with Express.js?
Our team at Slashdev.io builds production-ready Express.js applications.