Open In App

Middleware in Express

Last Updated : 26 Feb, 2025
Summarize
Comments
Improve
Suggest changes
Like Article
Like
Share
Report
News Follow

Middleware functions are the building blocks of any web server, especially in frameworks like ExpressJS. It plays a vital role in the request-response cycle. They 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.

What is Middleware in Express?

Middleware in Express refers to functions that process requests before reaching the route handlers. These functions can modify request and response objects, end the request-response cycle, or call the next middleware function.

  • Middleware functions are executed in the order they are defined.
  • They can perform tasks like authentication, logging, or error handling.
  • Middleware helps separate concerns and manage complex routes efficiently.
middleware working

Middleware working

Syntax

app.use((req, res, next) => {
console.log('Middleware executed');
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.

How Middleware Works in Express.js?

In Express.js, middleware functions are executed sequentially in the order they are added to the application. When a request is received, it is passed through the middleware functions in the order they were defined. Each middleware can perform a task and either send a response or call the next() function to pass control to the next middleware function.

Here’s how the typical flow looks:

  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

ExpressJS offers different types of middleware and you should choose the middleware based on functionality required.

  • Application-level middleware: Bound to the entire application using app.use() or app.METHOD() and executes for all routes.
  • Router-level middleware: Associated with specific routes using router.use() or router.METHOD() and executes for routes defined within that router.
  • Error-handling middleware: Handles errors during the request-response cycle. Defined with four parameters (err, req, res, next).
  • Built-in middleware: Provided by Express (e.g., express.static, ExpressJSon, etc.).
  • Third-party middleware: Developed by external packages (e.g., body-parser, morgan, etc.).

Steps to Implement Middleware in Express

Step 1: Initialize the Node.js Project

npm init -y

Step 2: Install the required dependencies.

npm install express

Step 3: Set Up the Express Application

// Filename: index.js
const express = require('express');
const app = express();
const port = process.env.PORT || 3000;

app.get('/', (req, res) => {
  res.send('<div><h2>Welcome to GeeksforGeeks</h2><h5>Tutorial on Middleware</h5></div>');
});

app.listen(port, () => {
  console.log(`Listening on port ${port}`);
});

Step 4: Start the Application:

node index.js

Output:

When you navigate to http://localhost:3000/, you will see:

Welcome to GeeksforGeeksTutorial on Middleware

Middleware Chaining

Middleware can be chained from one to another, Hence creating a chain of functions that are executed in order. The last function sends the response back to the browser. So, before sending the response back to the browser the different middleware processes the request.

The next() function in the express is responsible for calling the next middleware function if there is one.

Modified requests will be available to each middleware via the next function

middleware chaining example

Middleware chaining example

const express = require('express');
const app = express();

// Middleware 1: Log request method and URL
app.use((req, res, next) => {
    console.log(`${req.method} request to ${req.url}`);
    next();
});

// Middleware 2: Add a custom header
app.use((req, res, next) => {
    res.setHeader('X-Custom-Header', 'Middleware Chaining Example');
    next();
});

// Route handler
app.get('/', (req, res) => {
    res.send('Hello, World!');
});

app.listen(3000, () => {
    console.log('Server is running on port 3000');
});
  • Middleware 1: Logs the HTTP method and URL of the incoming request.
  • Middleware 2: Sets a custom header X-Custom-Header in the response.
  • Route Handler: Sends a “Hello, World!” message as the response.

Output

When a client makes a GET request to http://localhost:3000/, the server responds with:

Hello, World!

Advantages of using Middleware

  • Modularity: Breaks down complex tasks into smaller, manageable functions.
  • Reusability: Middleware functions can be reused across different routes or applications.
  • Maintainability: Organizes code logically, making it easier to manage and update.
  • Error Handling: Centralizes error handling, improving the application’s robustness.
  • Performance Optimization: Allows for tasks like caching, compression, and security checks to be handled efficiently.

Best Practices for Middleware in ExpressJS

  • Always call next() to pass control to the next middleware unless you are ending the request-response cycle.
  • Use specific middleware for different tasks (e.g., authentication, logging) to keep the code modular and clean.
  • Place error-handling middleware at the end of the middleware stack to catch any unhandled errors.
  • Avoid using synchronous code in middleware to prevent blocking the event loop.

Middleware in ExpressJS – FAQs

What is the purpose of next() in Express middleware?

next() is used to pass control to the next middleware function in the stack. If it’s not called, the request will be left hanging and no further middleware will be executed.

How do I handle errors in middleware?

Express provides a special error-handling middleware that takes four arguments: (err, req, res, next). You can define it at the end of your middleware stack to handle errors globally.

Can middleware be applied to specific routes?

Yes, you can apply middleware to specific routes or routers by using app.METHOD(path, middleware) or router.METHOD(path, middleware).

Is it a good practice to have large middleware functions?

It’s better to keep middleware functions small and focused on a single task, making them easier to maintain and debug.

How can I avoid security issues with middleware?

Use middleware like ExpressJSon() for parsing JSON requests and consider implementing security-focused middleware such as helmet for protecting HTTP headers.



Next Article

Similar Reads

three90RightbarBannerImg