Creating Custom Middleware in Node.js
Explore techniques for developing reusable middleware components to streamline request processing in your Node.js applications.
0 likes
40 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!'); });