Introduction
Middleware is a fundamental concept in Express.js that allows developers to process and manipulate requests before they reach their final destination. Middleware functions provide a way to handle logging, authentication, error handling, and more within Express applications.
In this guide, we’ll explore:
- What middleware is
- Types of middleware in Express.js
- How to create custom middleware
- Real-world use cases for middleware
By the end of this article, you’ll have a solid understanding of how to use middleware effectively in your Express applications.
1. What is Middleware in Express.js?
Middleware functions in Express.js are functions that execute during the request-response cycle. These functions have access to the request object (req
), the response object (res
), and the next
function, which passes control to the next middleware function.
Middleware Function Syntax:
app.use((req, res, next) => {
console.log('Middleware function executed');
next(); // Pass control to the next middleware
});
How Middleware Works
When a request is made to an Express server, it goes through a sequence of middleware functions before sending a response. Each middleware function can:
- Modify the request (
req
) and response (res
) objects - End the request-response cycle
- Call
next()
to pass control to the next middleware
2. Types of Middleware in Express.js
1. Built-in Middleware
Express provides some built-in middleware functions:
express.json()
→ Parses incoming JSON requestsexpress.urlencoded()
→ Parses URL-encoded payloadsexpress.static()
→ Serves static files (CSS, images, JavaScript)
Example:
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(express.static('public'));
2. Third-Party Middleware
These are middleware functions provided by npm packages. Popular ones include:
morgan
→ Logs HTTP requestscors
→ Handles Cross-Origin Resource Sharinghelmet
→ Secures apps by setting HTTP headers
Example:
const morgan = require('morgan');
const cors = require('cors');
const helmet = require('helmet');
app.use(morgan('dev'));
app.use(cors());
app.use(helmet());
3. Application-Level Middleware
These middleware functions are applied at the app level and run on every request.
Example:
app.use((req, res, next) => {
console.log(`Request Method: ${req.method}, Request URL: ${req.url}`);
next();
});
4. Route-Specific Middleware
Middleware can be applied to specific routes.
Example:
const checkAuth = (req, res, next) => {
if (req.headers.authorization) {
next();
} else {
res.status(403).send('Unauthorized');
}
};
app.get('/protected', checkAuth, (req, res) => {
res.send('You have access!');
});
5. Error-Handling Middleware
This type of middleware is used to catch and handle errors.
Example:
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Something went wrong!');
});
3. Creating Custom Middleware in Express
You can create your own middleware functions for tasks like logging, authentication, or modifying request data.
Example: Custom Logging Middleware
const requestLogger = (req, res, next) => {
console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
next();
};
app.use(requestLogger);
Example: Authentication Middleware
const authenticateUser = (req, res, next) => {
if (req.headers.authorization === 'secret-token') {
next();
} else {
res.status(401).send('Unauthorized');
}
};
app.get('/dashboard', authenticateUser, (req, res) => {
res.send('Welcome to the dashboard');
});
4. Real-World Use Cases for Middleware
Middleware is widely used in Express applications for various purposes:
1. Logging Requests
Using morgan
to log HTTP requests:
const morgan = require('morgan');
app.use(morgan('combined'));
2. Handling CORS (Cross-Origin Requests)
Allowing external domains to access your API:
const cors = require('cors');
app.use(cors());
3. Serving Static Files
Serving images, CSS, and JavaScript:
app.use(express.static('public'));
4. Error Handling
Catching and handling errors globally:
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Internal Server Error');
});
5. Best Practices for Using Middleware
To optimize middleware usage in Express applications, follow these best practices:
- Order Matters → Place middleware in the correct sequence, e.g., logging first, then authentication, then routes.
- Use Third-Party Middleware → Avoid reinventing the wheel; leverage packages like
morgan
,helmet
, andcors
. - Limit Middleware Scope → Apply middleware only where necessary (e.g., route-specific middleware).
- Handle Errors Properly → Always include an error-handling middleware at the end of your stack.
- Optimize Performance → Minimize unnecessary middleware execution by structuring routes efficiently.
6. Conclusion
Middleware is a powerful feature in Express.js that enhances the functionality, security, and maintainability of web applications. By understanding its types, creating custom middleware, and using third-party solutions, you can build scalable and efficient applications.
Next Steps
- Implement authentication using JWT middleware.
- Build a middleware-based rate-limiting system.
- Optimize error handling for production.
Start experimenting and take your Express skills to the next level! 🚀