Introduction
Express applications rely on middleware and routers to structure and streamline web application logic. Middleware functions enable handling requests and responses at different stages, while routers help organize and manage endpoints efficiently. By mastering these tools, you can create modular and scalable Express applications.
Key Objectives
After completing this lesson, you will be able to:
- Compare and contrast an Express application and an Express router.
- Create a resource for RESTful routes using an Express router.
- Connect an Express router to an Express application.
- Add middleware globally, to a specific route, and/or to a specific router.
- Predict the order of execution for middleware functions.
- Define middleware and its purpose.
- Create middleware using functions or arrays of functions.
- Differentiate between regular middleware and error-handling middleware in Express.
What is Middleware?
Middleware functions are functions that have access to the req (request), res (response), and next objects. They execute specific logic, modify request and response objects, and determine whether to pass control to the next middleware function.
const express = require('express');
const app = express();
// Example middleware function
app.use((req, res, next) => {
console.log('Request URL:', req.url);
next(); // Pass control to the next middleware
});
Creating Middleware
1. Regular Middleware
A regular middleware function handles a variety of tasks, such as logging, parsing, or adding custom properties to requests.
// Logging middleware
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`);
next();
});
2. Error-Handling Middleware
Error-handling middleware functions handle errors that occur in the application. These functions have four parameters: err, req, res, and next.
// Error-handling middleware
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Something broke!');
});
Using Routers
Routers help organize application logic by grouping related routes together.
// Defining a router
const express = require('express');
const userRouter = express.Router();
// Add routes to the router
userRouter.get('/', (req, res) => {
res.send('List of users');
});
userRouter.post('/', (req, res) => {
res.send('Create a new user');
});
// Connect the router to the application
app.use('/users', userRouter);
Middleware Order of Execution
Middleware functions are executed in the order they are defined. This order is critical for application behavior:
// Middleware 1
app.use((req, res, next) => {
console.log('Middleware 1');
next();
});
// Middleware 2
app.use((req, res, next) => {
console.log('Middleware 2');
next();
});
In the above example, Middleware 1 runs before Middleware 2.
Best Practices
- Use routers to group related routes for better organization.
- Order middleware logically to avoid unintended behaviors.
- Leverage error-handling middleware for consistent error management.
- Apply global middleware sparingly to maintain performance.