NodeJS Middleware
What is Middleware in Node Js?
Middleware in [Link] refers to a concept where functions can be used to process incoming requests
before they reach their final destination and handle outgoing responses before they are sent back to the
client. These functions sit in between the initial request and the final response, hence the term
“middleware.”
In [Link] (with [Link]), middleware is a function that sits between the request and the
response.
It processes requests before they reach the final route handler or before sending a response.
In simple terms:
Middleware functions are like checkpoints that requests pass through.
They can modify request (req) and response (res) objects.
They can end the response or pass control to the next middleware using next() .
How Does [Link] Middleware Pattern Work?
In [Link], middleware functions are essentially functions that have access to the request object ( req ),
the response object ( res ), and the next function in the application's request-response cycle.
When a request is made to the server, it passes through a series of middleware functions before
reaching the final route handler or endpoint.
Each middleware function can perform its task and either pass the request to the next middleware
function using the next function or terminate the request-response cycle by sending a response.
What happens when the request reaches the last middleware in the chain
?
1. The request passes through all middleware functions in the chain.
2. If none of the middleware functions send a response back to the client (i.e., they all call the next()
function to pass control to the next middleware or route handler):
Express looks for a matching route handler based on the request URL and HTTP method.
If a matching route handler is found, it is executed.
If no matching route handler is found, Express sends a default “Not Found” response back to the
client with a status code of 404.
What is next() ?
In [Link], next() is a function that is used within middleware functions to pass control to the next
middleware function in the chain. When next() is called within a middleware function, Express moves
to the next middleware function defined in the application.
When a middleware function is defined, it typically receives three arguments: req (the request object),
res (the response object), and next (the next middleware function in the chain). By calling next()
within a middleware function, the control is passed to the subsequent middleware function.
Some common used Middleware
cors : Enable cross-origin resource sharing (CORS) with various options.
cookie-parser : Parse cookie header and populate [Link].
morgan : HTTP requests logger.
multer : Handle multi-part form data.
Middleware Chaining
Generally, a set of middlewares are chained to form a set of functions that execute one after the other in
order.
The next() function is called at the end of every middleware to pass the control to the next middleware.
The last middleware function sends back the response to the client. Hence, different middleware
process the request before the response is sent back.
Syntax :
(req, res, next) => {
// body of middleware
next();
}
(req, res, next) => {}: This is the middleware function where you can perform actions on the
request and response objects before the final handler is executed.
next(): This function is called to pass control to the next middleware in the stack if the current one
doesn't end the request-response cycle.
What Middleware Does in [Link]
Middleware functions in [Link] can perform several important tasks:
1. Execute Code: Middleware can run any code when a request is received.
2. Modify Request and Response: Middleware can modify both the request (req) and response
(res) objects.
3. End the Request-Response Cycle: Middleware can send a response to the client, ending the
cycle.
4. Call the Next Middleware: Middleware can call next() to pass control to the next function in the
middleware stack.
How Middleware Works in [Link]?
In [Link], middleware functions are executed sequentially in the order they are added to the
application. Here’s how the typical flow works:
1. Request arrives at the server.
2. Middleware functions are applied to the request, one by one.
3. Each middleware can either:
Send a response and end the request-response cycle.
Call next() to pass control to the next middleware.
4. If no middleware ends the cycle, the route handler is reached, and a final response is sent.
Types of Middleware in [Link]
1. Application-level middleware
In the application-level middleware, we consider an authentication middleware and how it can be
created. When the user is not authenticated, it will not be possible to call the mentioned routes. When it
is necessary to build an authentication for every GET, POST call, the development of an authentication
middleware will follow.
When you receive the authentication request, the authentication middleware makes progress towards
the authentication code logic that is available inside it. Once the authentication is successful, the rest of
the route can be called using the next function. However, when it fails, you may not be able to perform
the next route as the middleware will show errors.
2. Router-level middleware
Router-level middleware is almost like the application-level middleware and works in the same way. The
difference is that it can generate and limit an instance using the [Link]() function. You can
make use of the [Link]() and [Link]() functions to load router-level middleware.
3. Build-in middleware
The build-in middleware doesn't depend on the ‘Connect’ function and unlike the previous 4.X version
types, Express now acts as a module. Generally, under the Express types of middleware, you can utilize
these listed middleware functions:
json - a function that computes the incoming request by adding JSON payloads
static - a function that acts as a static asset to the application.
4. Error-handling middleware
[Link] is capable of handling any default errors and can also define error-handling middleware
functions, which are similar to the other middleware functions. The major difference is the error-handling
functions.
5. Third-party middleware
Sometimes, you will need to have some additional features in the backend operations. For that, you can
install the [Link] module for the specific function and then apply the same to your application (either
on the application or router level).
Example 1: Simple Middleware
const express = require("express");
const app = express();
// Application-level middleware
[Link]((req, res, next) => {
[Link]("Middleware executed:", [Link], [Link]);
next(); // pass control to the next middleware/route
});
[Link]("/", (req, res) => {
[Link]("Hello, Middleware!");
});
[Link](3000, () => {
[Link]("Server running on [Link]
});
Output:
in console:
Server running on [Link]
Middleware executed: GET /
Example 2: Multiple Middlewares
const express = require("express");
const app = express();
// Middleware 1
[Link]((req, res, next) => {
[Link]("First Middleware");
next();
});
// Middleware 2
[Link]((req, res, next) => {
[Link]("Second Middleware");
next();
});
// Route
[Link]("/", (req, res) => {
[Link]("Final Response");
});
[Link](3000, () => [Link]("Server running on [Link]
Output:
in Console:
First Middleware
Second Middleware
Example 3: Route-Specific Middleware
const express = require("express");
const app = express();
function checkAuth(req, res, next) {
const isLoggedIn = true; // assume from DB/session
if (isLoggedIn) {
next();
} else {
[Link](403).send("Unauthorized!");
}
}
[Link]("/", (req, res) => {
[Link]("Public Route");
});
// Applying middleware only to this route
[Link]("/dashboard", checkAuth, (req, res) => {
[Link]("Protected Dashboard");
});
[Link](3000, () => [Link]("Server running on [Link]
Output:
/dashboard will only work if checkAuth passes.
Example 4: Error-Handling Middleware
Error-handling middleware has 4 parameters: (err, req, res, next) .
const express = require("express");
const app = express();
[Link]("/", (req, res) => {
throw new Error("Something went wrong!");
});
// Error-handling middleware
[Link]((err, req, res, next) => {
[Link]([Link]);
[Link](500).send("Internal Server Error!");
});
[Link](3000, () => [Link]("Server running on [Link]
Any error will be caught here.
Example 5: Built-in Middleware
const express = require("express");
const app = express();
// [Link]() parses JSON request body
[Link]([Link]());
// [Link]() serves static files
[Link]([Link]("public"));
[Link]("/data", (req, res) => {
[Link](`Received: ${[Link]([Link])}`);
});
[Link](3000, () => [Link]("Server running on [Link]
If you send JSON with Postman, it will be parsed automatically.
Example 6: Third-Party Middleware
As we need to use the third-party middleware, we need to install it using npm. So for this , we will be
using third-party middleware as a body-parser. So install it using the below command.
npm i body-parser
Write the following code in [Link] file
const express = require('express');
const parser = require('body-parser');
const app = express();
const port = 3000;
// Using body-parser middleware to parse JSON requests
[Link]([Link]());
[Link]('/api/data', (req, res) => {
const reqData = [Link];
[Link]('Received data:', reqData);
[Link](200).json({ message: 'Data received successfully!' });
});
[Link](port, () => {
[Link](`Server is running on [Link]
});
To run the application, we need to start the server by using the below command.
node [Link]
Explanation:
In the above example, we have used third-party middleware as a body-parser. We have
integrated it using '[Link]()'.
Then we configured the body-parser to parse incoming JSON requests in the handler 'api/data'.
By using the [Link] in the POST request handler we can access and process the parsed JSON
data.