Express Middleware and Router Objectives

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:

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