Placement-ready Online Courses: Your Passport to Excellence - Start Now
Middleware is a fundamental concept in Express.js that allows developers to add functionality to the request-response cycle.
Middleware functions are functions that have access to the request object (req), the response object (res), and the next function in the application’s request-response cycle. These can perform a variety of tasks, such as logging requests, parsing request bodies, authenticating users, and handling errors. In this article, we will explore how to use middleware in Express.js.
Prerequisites to learn about Middleware in Express JS
Before diving into middleware, it is important to have a good understanding of Node.js and HTTP concepts, as well as the basic structure and syntax of Express.js. Additionally, a basic knowledge of JavaScript and ES6 syntax will be helpful.
Table Built-In Middleware:
Express.js provides several built-in middleware functions that can be used out of the box. One of the most common is the express.static() middleware, which is used to serve static files such as images, CSS, and JavaScript files. Another useful built-in middleware is body-parser, which is used to parse the request body of a HTTP request.
Parsing Payloads:
When working with HTTP requests, it is often necessary to parse the payload data, such as the request body or URL parameters. Express.js provides several built-in middleware functions to handle payload parsing. For example, the body-parser middleware can be used to parse JSON, URL-encoded, or multipart form data from the request body.
Custom Middleware Functions in Express JS:
In addition to built-in middleware, Express.js allows developers to create custom middleware functions that can be used to perform any operation on the incoming request or outgoing response. Custom middleware functions can be created using the app.use() method, which registers the middleware function in the middleware stack. Custom middleware functions can also be used to add custom properties or methods to the request or response objects.
Types of Middleware in ExpressJS
There are three types of middleware in Express.js:
1. Error Handling:
Express.js provides a powerful error handling mechanism that allows developers to handle errors in a centralized way. Error handling middleware can be registered using the app.use() method, and can be used to catch and handle errors thrown by the application code or other middleware functions. These middleware can also be used to log errors or return custom error messages to the client.
Error-handling middleware is middleware that is used to handle errors that occur during the request-response cycle. It is defined using a special four-argument middleware function that takes an error object as its first argument.
Example of defining error-handling middleware
const express = require('express');
const app = express();
// Define a route
app.get('/', (req, res) => {
throw new Error('Something went wrong');
});
// Define error-handling middleware
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Something broke!');
});
// Start the server
app.listen(3000, () => {
console.log('Server started on port 3000');
});
In this example, we have defined a route that intentionally throws an error. We then define error-handling middleware using the app.use() method, which logs the error and sends a
500 response to the client.
2. Application-level Middleware
Application-level middleware is middleware that is bound to an instance of the express application object. It can be used to define behavior that should be applied to all requests received by the application. Common use cases for application-level middleware include logging requests, parsing request bodies, and setting headers.
Example of defining application-level middleware
const express = require('express');
const app = express();
// Define application-level middleware
app.use((req, res, next) => {
console.log('Request received:', req.url);
next();
});
// Define a route
app.get('/', (req, res) => {
res.send('Hello World!');
});
// Start the server
app.listen(3000, () => {
console.log('Server started on port 3000');
});
In this example, we have defined a middleware function using the app.use() method. This middleware function logs the URL of each request received by the application.
3. Router-level Middleware
Router-level middleware is middleware that is bound to an instance of an Express.js router object. It can be used to define behavior that should be applied to all requests that match a specific route. Common use cases for router-level middleware include authenticating users and handling errors.
Example of defining router-level middleware
const express = require('express');
const app = express();
const router = express.Router();
// Define router-level middleware
router.use((req, res, next) => {
console.log('Request received:', req.url);
next();
});
// Define a route
router.get('/', (req, res) => {
res.send('Hello World!');
});
// Use the router in the application
app.use('/', router);
// Start the server
app.listen(3000, () => {
console.log('Server started on port 3000');
});
In this example, we have defined a middleware function using the router.use() method. This middleware function logs the URL of each request that matches the route defined by the router. We then use the router in the application using the app.use() method.
Using Third-party Middleware
In addition to the built-in middleware provided by Express.js, developers can also use third-party middleware to add additional functionality to their applications. There are a number of third-party middleware libraries available on npm that can be easily installed and used in an Express.js application.
One popular example of third-party middleware is body-parser, which is used to parse request bodies. To use body-parser in an Express.js application, we would first need to install it using npm:
Body Parser Middleware
npm install body-parser
We would then use it in our application as follows:
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
// Use body-parser middleware
app.use(bodyParser.json());
// Define a route
app.post('/user', (req, res) => {
const user = req.body;
console.log(user);
res.send('User created!');
});
// Start the server
app.listen(3000, () => {
console.log('Server started on port 3000');
});
In this example, we have used the body-parser middleware to parse JSON request bodies. We then define a route that creates a new user based on the JSON data sent in the request body.
Diagram that illustrates the middleware architecture in Express.js:
Structure
+——————+
| Global Middleware|
+——————+
|
V
+——————+
| Route-specific |
| Middleware |
+——————+
|
V
+——————+
| Final Handler |
+——————+
Advantages of using middleware architecture in Express.js:
1. Modularization: Middleware functions can be modularized and reused in different routes, making it easier to maintain the code and reduce redundancy.
2. Improved performance: Middleware functions can perform common operations on incoming requests and outgoing responses, reducing the amount of duplicated code and improving the overall performance of the application.
3. Error handling: Middleware functions can handle errors and exceptions in a centralized location, making it easier to debug and maintain the code.
4. Flexible: Middleware architecture is flexible and can be customized to suit the needs of the application. Middleware functions can be added, removed, or modified as per the requirements.
Configurable Middleware
Configurable middleware allows developers to pass parameters or options to the middleware function at runtime, making it more flexible and adaptable to different use cases. This can be achieved by wrapping the middleware function inside another function that takes the parameters or options as arguments.
Here is an example of configurable middleware in Express.js:
function myMiddleware(options) {
return function(req, res, next) {
// use options here
console.log(options.message);
next();
}
}
app.use(myMiddleware({ message: "Hello World" }));
In this example, myMiddleware is a configurable middleware function that takes an options object as an argument and returns another middleware function that takes the standard req, res, and next arguments. The options object can be used to configure the middleware behavior, such as setting a message to be displayed in the console.
To use the middleware, we pass the options object to myMiddleware using the app.use() method. This will create an instance of the middleware function with the specified options and add it to the middleware stack.
Configurable middleware can be very useful when working with complex applications that require different middleware configurations for different routes or environments. By making the middleware configurable, we can reuse the same middleware function across multiple routes and environments with different configurations.
In addition to passing parameters or options, configurable middleware can also be implemented using a factory function that returns a new middleware function with custom behavior.
Conclusion
Middleware is a powerful concept in Express.js that allows developers to easily add functionality to the request-response cycle. By using built-in middleware, third-party middleware, and custom middleware, developers can create highly customizable applications that meet the specific needs of their users.
