
Middleware is the secret sauce behind Node.js applications, acting as a bridge between incoming requests and final responses. It plays a crucial role in handling various aspects of request processing, such as authentication, logging, data validation, and error handling. In Express.js, middleware functions execute sequentially, modifying the request or response object as needed before passing control to the next function. There are three main types of middleware: built-in, third-party, and custom middleware. Built-in middleware like express.json()
helps parse JSON payloads, while third-party middleware like cors
enables cross-origin requests. Custom middleware allows developers to implement specific logic, such as user authentication or rate limiting, ensuring efficient request handling and improved application security.
What is Middleware?
Middleware functions:
- Execute during an HTTP request-response cycle
- Access request (req) and response (res) objects
- Perform tasks like logging, authentication, or data parsing
- Can end the cycle or pass control using next()
// Basic middleware example
app.use((req, res, next) => {
console.log(`Request received: ${req.method} ${req.url}`);
next(); // Pass control to next middleware
});
Types of Middleware
1. Application-Level Middleware in Node.js
Applies to all routes:
app.use(express.json()); // Parse JSON bodies
app.use(cors()); // Enable CORS
2. Router-Level Middleware
Applies to specific routes:
const authRouter = express.Router();
authRouter.use(checkAuth); // Authentication middleware
3. Error-Handling Middleware
Handles errors (4 arguments):
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Server Error!');
});
4. Built-in Middleware
Express essentials:
app.use(express.json()); // Replaces body-parser
app.use(express.urlencoded({ extended: true }));
5. Third-Party Middleware
Popular npm packages:
Middleware | Purpose | Install Command |
---|---|---|
Helmet | Security headers | npm install helmet |
Morgan | Request logging | npm install morgan |
Passport | Authentication | npm install passport |
Creating Custom Middleware
Authentication Example:
const checkAuth = (req, res, next) => {
const token = req.headers.authorization;
if (validateToken(token)) {
next(); // Authorized
} else {
res.status(401).json({ error: 'Unauthorized' });
}
};
// Usage
app.get('/dashboard', checkAuth, (req, res) => {
res.send('Protected Content');
});
Logging Middleware:
const requestLogger = (req, res, next) => {
const log = `${new Date().toISOString()} - ${req.method} ${req.path}`;
fs.appendFile('logs.txt', log + '\n', (err) => {
if (err) console.error('Logging failed');
});
next();
};
Middleware Execution Order
Order matters! Middleware executes sequentially:
app.use(helmet()); // 1. Security first
app.use(express.json()); // 2. Parse body
app.use(requestLogger); // 3. Log requests
app.use('/api', apiRouter); // 4. Route handlers
app.use(errorHandler); // 5. Catch errors LAST
Common Mistakes & Best Practices
✅ Do:
- Always call
next()
unless terminating the request - Place error handlers after other middleware
- Use specific middleware for routes when possible
❌ Avoid:
- Blocking operations in middleware (use async/await)
- Overloading middleware with multiple responsibilities
- Ignoring error handling in async middleware