Creating a middleware in ExpressJS
Creating a Middleware in Express.js
In the last lecture, we covered the concept of middleware in Express.js, and now we're ready to take it a step deeper by learning how to create our own middleware. Middleware is a powerful tool that allows you to add custom functionality to your server, such as error handling, request processing, or adding common behaviors to all routes. In this tutorial, we will explore how to create our own custom middleware that handles requests in a versatile way.
What is Middleware?
Middleware functions in Express.js are pieces of code that run between the request and response lifecycle, allowing you to modify requests, responses, or add custom logic before the final response is sent back to the client. Middleware can be used to handle errors, log requests, validate data, or even modify response headers.
Creating a Custom Middleware
Let's dive right in and create our own middleware function that handles "404 - Page Not Found" errors. Typically, when a user requests a URL that doesn't exist, you want to let them know with a custom error page or message. Express.js doesn't handle 404 errors by default, as it's an unopinionated framework that gives developers flexibility to define their own rules. That's where middleware comes into play.
Step 1: Setting Up the Middleware
The middleware function we're going to create will catch any request that wasn't handled by our route definitions. To do that, we will add our middleware to the very bottom of the route definitions, ensuring it only runs after all other routes have been evaluated.
Here's an example of what the middleware might look like:
// Custom 404 Middleware
app.use((req, res, next) => {
// Set the status code to 404, indicating page not found
res.status(404);
// Send an error message to the client
res.send('Sorry, I cannot find this page');
});
Step 2: Understanding the Middleware Structure
In the code above, the function has three parameters: req
, res
, and next
.
- req: The request object that contains information about the client's request, such as URL, headers, and body.
- res: The response object that allows you to send back a response to the client.
- next: A callback function that allows you to pass control to the next middleware in the stack, if any.
Since this middleware is designed to handle errors (specifically, "404 - Not Found" errors), there is no next()
call in this example. Once the middleware is reached, it sets the status to 404 and sends a custom error message back to the client.
Step 3: Using Middleware in Express.js
Middleware can be placed anywhere in the request-response lifecycle, and their order is important. Here, we add our custom middleware at the very end, making sure it runs after all the defined routes:
// Other route handlers\...
// Custom 404 Middleware must be placed at the end\app.use((req, res) => {
res.status(404).send('Sorry, I cannot find this page');
});
Advanced Middleware Concepts
Middlewares can be much more powerful when you need them to be. For example, you can use middleware to perform logging, check user authentication, or even add custom headers. You can also use the next()
function to pass control to the next middleware if multiple middlewares need to run for the same request.
In this example, the next
callback is used when middleware is not the endpoint of a request and other handlers need to be executed afterward. This approach is beneficial if you need to create reusable functions to enhance your application.
app.use((req, res, next) => {
console.log('Time:', Date.now());
next();
});
Practical Usage
In our middleware example, we created a basic "404 - Not Found" handler. You could expand this handler to include more informative responses, such as a redirect to a help page or logging the error to a database.
The next()
function becomes particularly useful when chaining multiple middleware functions. For example, you could use it to log requests before passing them on to your route handlers.
// Log request information middleware
app.use((req, res, next) => {
console.log(`Request URL: ${req.url}`);
console.log(`Request Method: ${req.method}`);
next(); // Pass control to the next middleware or route handler
});
In a real-world application, you could add custom error pages, user-friendly messages, or even dynamic redirects based on user roles or permissions.
Updates Since 2016
Note: Since this video was created in 2016, some best practices around middleware have evolved.
- Deprecation of Body Parser: In Express version 4.16.0+,
body-parser
has been added as part of the Express module itself. Instead of installing and usingbody-parser
, you can now useexpress.json()
andexpress.urlencoded()
. - Arrow Functions: This example uses modern JavaScript arrow functions, which may not have been common in 2016 but are widely adopted today for cleaner and more concise syntax.
Summary
In this tutorial, we learned how to create a custom middleware in Express.js to handle 404 errors. Middleware is a powerful tool that allows us to extend the functionality of our application, whether it's handling errors, logging, or other utilities. In the next lesson, we will explore automating the process of creating applications using the Express generator.