Express is a widely used framework of Node.js for backend development. Express provides robust middleware support, which helps developers write reusable and maintainable code.
In this blog, we are diving deep into middleware. By the end of this blog, you will understand all the important concepts of middleware.
What is Middleware?
Middleware is a function that runs during the request-response cycle, sitting between the incoming request and the final route handler.
Every middleware function accepts three arguments:
req(request)res(response)next
req (Request)
The request object contains incoming data sent by the client.
res (Response)
The response object is used by the server to send data back to the client.
next()
The next() function passes control to the next middleware function. If there is no next middleware, the request moves to the final route handler.
Important Note
A middleware must either end the request-response cycle by sending a response using res.send() (or similar methods) or pass control using next(). Otherwise, the client request will remain hanging between the request and response cycle.
Types of Middleware :
-
Application-level middleware :
Application-level middleware is bound to the Express application instance usingapp.use()andapp.METHOD()functions.It runs for every incoming request to the server if a specific path is not provided.
The execution of middleware follows a top-to-bottom order. Middleware declared at the top runs first, followed by the next middleware in sequence.
For example, if multiple middleware functions are registered using
app.use(), Express executes them one by one in the same order they are written in the code.It has full access to the
req(request) object,res(response) object, and thenext()function throughout the request-response cycle
const express = require('express'); const app = express(); // 1. Without a mount path: Executes for every request app.use((req, res, next) => { console.log('Time:', Date.now()); next(); // Pass control to the next function }); // 2. With a mount path: Executes for any request to /user/:id app.use('/user/:id', (req, res, next) => { console.log('Request Type:', req.method); next(); }); // 3. With a method: Executes only for GET requests to /user/:id app.get('/user/:id', (req, res, next) => { res.send('User Page'); }); -
Router-level middleware :
Router-level middleware is bound to the instance of router not in main application instance which allow use to apply middleware function to a specific router making our code more modular.Router-level middleware runs for a specific request that match the path mount to the middleware . It not runs for every request.
const express = require('express'); const router = express.Router(); // This middleware is executed for every request to this router router.use((req, res, next) => { console.log('Router-level request received at:', Date.now()); next(); }); // Define routes within this router router.get('/profile', (req, res) => { res.send('User Profile'); }); // Mount the router on a path in the main app // Only requests starting with /user will trigger the router's middleware const app = express(); app.use('/user', router); -
Built-in :
Built-in middleware is bound to the instance of app. They are build in middleware of express we don't need the write logic from scratch.The primary built-in middleware functions are:
express.json(): Parses incoming requests with JSON payloads. It makes the parsed data available underreq.body.-
express.urlencoded({ extended: true }):express.urlencoded()is a built-in middleware in Express.js used to parse incoming form data sent from the client.When user submit HTML form data is usually send in this format :
application/x-www-form-urlencoded
This middleware converts that form data into a JavaScript object and stores it inside req.body.
Example :
app.use(express.urlencoded({ extended: true }));
express.static(): Serves static files such as images, CSS, and JavaScript from a specified directory (e.g.,app.use(express.static('public'))).express.text(): Parses incoming request payloads into a string.
Error-handling : Error handling is a specialized middleware used to catch and process errors in an Express application.
To create an error-handling middleware, you must define a function with four parameters:
(err, req, res, next)
err : Contains information about the error
Code example :
app.use((err, req, res, next) => {
console.error(err.message);
res.status(500).send("Something went wrong");
});
Now we understand the middleware with their types :
Let's dive into the execution order of middleware :
In express middleware run sequently in the order as they defined in code. When a request received express passes it through the middleware stack one by one until the response is send res.send() or stack become empty.
Execution Rules :
Definition Order : The order of app.use() and app.METHOD() (like app.get or app.post) calls determines the execution sequence.
next() function : Function: To move to the subsequent middleware, you must call next(). If you don't call it and don't send a response, the request will hang.
Terminating the Cycle: If a middleware sends a response (e.g., res.send() or res.json()), the request-response cycle ends, and subsequent middleware in the stack will not execute.
Real work example of middleware :
One of the real world use case of middleware is authentication used in real world applications like Instagram , Amazon etc.
Suppose user try to access dashboard
middleware checks :
is token valid
user is logged in or not
-
does the user have permission to access the dashboard
This checking logic written inside middleware.
function authMiddleware(req, res, next) {
const isLoggedIn = true;
if (!isLoggedIn) {
return res.status(401).send("Please login first");
}
next();
}
app.get("/dashboard", authMiddleware, (req, res) => {
res.send("Welcome to your dashboard");
});
How it works :
Client Request
↓
Authentication Middleware
↓
Route Handler
↓
Response
if user logged in middleware call next() and move the route handler otherwise middleware return response.
Summary : In this blog, we learned that middleware works like a middleman between the request and response cycle. We explored different types of middleware and understood how middleware execution order works in Express.
Top comments (0)