Creating Custom Middleware in Node.js
Explore techniques for developing reusable middleware components to streamline request processing in your Node.js applications.
0 likes
168 views
Rule Content
---
title: Creating Custom Middleware in Node.js
description: Explore techniques for developing reusable middleware components to streamline request processing in your Node.js applications.
category: Node.js Cursor Rules
---
# Creating Custom Middleware in Node.js
## Context
- Applicable when developing middleware functions in Node.js applications.
- Assumes familiarity with Express.js or similar frameworks.
## Requirements
- **Single Responsibility Principle**: Ensure each middleware function performs a specific task to enhance maintainability and reusability.
- **Proper Error Handling**: Implement centralized error-handling middleware to manage errors effectively across the application.
- **Asynchronous Operations**: Utilize `async/await` syntax for asynchronous tasks to improve code readability and maintainability.
- **Middleware Order**: Arrange middleware functions in a logical sequence, placing critical operations like authentication and rate limiting early in the chain.
- **Named Functions**: Use named functions for middleware to facilitate debugging and improve code clarity.
- **Avoid Inline Middleware**: Define middleware functions separately from route handlers to maintain a clear separation of concerns.
## Examples
**Good Example: Single Responsibility Middleware**
// Logger Middleware
function loggerMiddleware(req, res, next) {
console.log('Request received:', req.url);
next();
}
// Authentication Middleware
function authenticationMiddleware(req, res, next) {
if (!req.isAuthenticated()) {
return res.status(401).send('Unauthorized');
}
next();
}
// Usage
app.use(loggerMiddleware);
app.use(authenticationMiddleware);
**Bad Example: Multiple Responsibilities in One Middleware**
app.use((req, res, next) => {
console.log('Request received:', req.url);
if (!req.isAuthenticated()) {
return res.status(401).send('Unauthorized');
}
next();
});
**Good Example: Centralized Error Handling**
// Error Handling Middleware
function errorHandler(err, req, res, next) {
console.error(err.stack);
res.status(500).send('Something broke!');
}
// Usage
app.use(errorHandler);
**Good Example: Asynchronous Middleware with async/await**
// Async Middleware
async function fetchDataMiddleware(req, res, next) {
try {
const data = await fetchData();
req.data = data;
next();
} catch (error) {
next(error);
}
}
// Usage
app.use(fetchDataMiddleware);
**Good Example: Proper Middleware Order**
app.use(authenticationMiddleware);
app.use(rateLimitingMiddleware);
app.use(loggerMiddleware);
app.use(responseModifierMiddleware);
**Good Example: Named Middleware Functions**
function loggerMiddleware(req, res, next) {
console.log('Request received:', req.url);
next();
}
app.use(loggerMiddleware);
**Bad Example: Anonymous Middleware Functions**
app.use((req, res, next) => {
console.log('Request received:', req.url);
next();
});
**Good Example: Separate Middleware and Route Handlers**
app.use(loggerMiddleware);
app.get('/', (req, res) => {
res.send('Hello from Express!');
});
**Bad Example: Mixing Middleware and Route Handlers**
app.get('/', (req, res) => {
app.use(loggerMiddleware); // Avoid using app.use() inside route handlers
res.send('Hello from Express!');
});