Express.js - Middleware
Middleware is a function that executes during the request-response cycle of an application. These functions have access to the request (req) and response (res) objects and can perform tasks such as logging, modifying requests, authentication, request parsing, and error handling.
Key Features of Middleware
- Execution Control : Controls the flow of the request-response cycle using next().
- Request Handling : Modifies, parses, or validates incoming requests.
- Response Handling : Modifies or ends the response sent to the client.
- Error Handling : Captures and processes errors in the application.
- Reusability : Modular functions that can be reused across routes.
- Chaining : Enables sequential execution of multiple middleware functions.
- Flexibility : Applicable globally or to specific routes as needed.
1. Application-level Middleware
Create a simple logging middleware to log incoming requests.
const express = require('express'); const app = express(); // Middleware to log the request time app.use((req, res, next) => { console.log(`[${new Date().toISOString()}] ${req.method} ${req.url} `); next(); // Proceed to the next middleware /route handler }); // Define a route handler for the home page app.get('/', (req, res) => { res.send('Welcome to the Home Page'); }); const PORT = 5000; app.listen(PORT, () => { console.log(`Server is running at http://localhost:${PORT}`); });
Run the Server
Run the server using the command given below.
node index.js
D:\my-app>node index.js Server is running on http://localhost:5000
Console Output
[2025-02-08T12:09:59.603Z] GET / [2025-02-08T12:10:03.848Z] GET /shop
2. Error-handling Middleware
Error-handling middleware in Express is a function that catches and handles errors. It uses four arguments (err, req, res, next) to process errors from routes or other middleware.
Error Handler
app.use((err, req, res, next) => { console.error('Error:', err.message); res.status(500).send('Internal Server Error'); });
3. Third-Party Middleware
Third-party middleware in Express comes from external libraries and is used for common tasks like security, logging, or handling cross-origin requests.
Using cors for Cross-Origin Requests
const cors = require('cors'); app.use(cors()); // Enables CORS for all routes
4. Built-in Middleware
Built-in middleware in Express are pre-defined functions that help with tasks like parsing request bodies, serving static files, or managing cookies. These are included in Express, so you don't need to write custom code for them.
app.use(express.json()); // Parse JSON bodies
app.use(express.urlencoded({ extended: true })); // Parse URL-encoded bodies
app.use(express.static('public')); // Serves static files
5. Custom Middleware
Custom middleware in Express.js is a function allow you add to custom logic like logging, authentication, validation or modifying requests before they reach the route handler. You can apply it globally or to specific routes.
i) Global Middleware
Global middleware in Express runs for all incoming requests, regardless of the route. It's defined with app.use()
const express = require('express'); const app = express(); // Global Middleware to check authentication const authenticate = (req, res, next) => { const token = req.headers['authorization']; if (token === 'my-token') { next(); // Allow the request to proceed } else { res.status(401).send('Unauthorized'); } }; // Apply the authenticate middleware globally (to all routes) app.use(authenticate); // Example routes app.get('/dashboard', (req, res) => { res.send('Welcome to the dashboard!'); }); app.get('/profile', (req, res) => { res.send('Welcome to the profile!'); }); const PORT = 5000; app.listen(PORT, () => { console.log(`Server is running at http://localhost:${PORT}`); });
- The authenticate middleware is now applied globally to all routes using app.use(authenticate).
- This means any route (/dashboard, /profile) will require the Authorization header to contain the correct token ('my-token').
- If the token is incorrect or missing, the request will be blocked with a 401 Unauthorized response.
ii) Route-Specific Middleware
Route-specific middleware in Express runs only for a specific route, not all routes.
In the following code, checkAdmin is route-specific middleware that checks if the username and password in the request body are valid, allowing the request to proceed only if they are correct.
const express = require('express'); const app = express(); app.use(express.json()); // To parse JSON bodies // Custom Middleware for specific route to check username, and password const checkAdmin = (req, res, next) => { const { username, password } = req.body; // Get username and password from the body // Check if username and password are valid if (username === 'admin' && password === '123') { next(); // Allow request to proceed } else { res.status(403).send('Invalid Credentials'); } }; // Apply middleware to a specific route app.get('/dashboard', checkAdmin, (req, res) => { res.send('Welcome to the dashboard page!'); }); // User route app.get('/user', (req, res) => { res.send('Welcome to the user page!'); }); const PORT = 5000; app.listen(PORT, () => { console.log(`Server is running at http://localhost:${PORT}`); });
6. Router-level Middleware
Router-level middleware in Express.js is middleware that is applies only to specific routes or groups of routes using an instance of express.Router().
const express = require('express'); const app = express(); app.use(express.json()); // To parse JSON bodies // Custom Middleware for specific route to check username, and password const checkAdmin = (req, res, next) => { const { username, password } = req.body; // Get username and password from the body // Check if username and password are valid if (username === 'admin' && password === '123') { next(); // Allow request to proceed } else { res.status(403).send('Invalid Credentials'); } }; // Create router const adminRouter = express.Router(); // Apply authentication middleware only to admin routes adminRouter.use(checkAdmin); // dashboard route adminRouter.get('/dashboard', (req, res) => { res.send('Welcome to the admin page!'); }); // profile route adminRouter.get('/profile', (req, res) => { res.send('Welcome to the admin profile page!'); }); const PORT = 5000; app.listen(PORT, () => { console.log(`Server is running at http://localhost:${PORT}`); });