Skip to main content

Command Palette

Search for a command to run...

What is Middleware in Express and How It Works

Updated
4 min read
What is Middleware in Express and How It Works
S

Learning web development in public. Writing simple, real-world explanations about web development concepts. Helping beginners understand why things work, not just how.

When building applications with Express, one concept you will see everywhere is middleware. It is one of the most important parts of how Express works.

If you understand middleware properly, you can control how requests are processed, validated, and handled in your application.


1. What Middleware is in Express

Middleware is simply a function that runs between the request and the response.

It has access to:

  • req (request)

  • res (response)

  • next (a function to move to the next step)

Basic structure:

function middleware(req, res, next) {
  // do something
  next();
}

Middleware can:

  • Modify request or response

  • Execute some logic

  • End the request-response cycle

  • Pass control to the next middleware


2. Where Middleware Sits in Request Lifecycle

When a client sends a request, it does not go directly to the route handler.

Instead, it passes through a chain of middleware functions.

Flow:

Request → Middleware → Middleware (if there in another one) → Route Handler → Response

Each middleware gets a chance to:

  • Process the request

  • Decide whether to continue or stop


3. Types of Middleware

Express provides different types of middleware based on how and where they are used.


a) Application-Level Middleware

These are applied to the entire app.

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

app.use((req, res, next) => {
  console.log('App-level middleware');
  next();
});

This runs for every request.


b) Router-Level Middleware

These are applied to specific routes using a router.

const router = express.Router();

router.use((req, res, next) => {
  console.log('Router-level middleware');
  next();
});

router.get('/users', (req, res) => {
  res.send('Users route');
});

app.use('/api', router);

This runs only for routes under /api.


c) Built-in Middleware

Express provides some built-in middleware.

Examples:

app.use(express.json());
app.use(express.urlencoded({ extended: true }));

These help in:

  • Parsing JSON

  • Handling form data


4. Execution Order of Middleware

Middleware runs in the order it is defined.

Example:

app.use((req, res, next) => {
  console.log('First');
  next();
});

app.use((req, res, next) => {
  console.log('Second');
  next();
});

app.get('/', (req, res) => {
  res.send('Done');
});

Output:

First
Second

If the order changes, the behaviour also changes.


5. Role of next() Function

The next() function is used to pass control to the next middleware.

If you do not call next():

  • The request will stop

  • The client will not get a response (request hangs)

Example:

app.use((req, res, next) => {
  console.log('Middleware running');
  next();
});

You can also stop the flow:

app.use((req, res) => {
  res.send('Request ended here');
});

6. Real-World Examples

Middleware is used in almost every backend application.


a) Logging

app.use((req, res, next) => {
  console.log(`\({req.method} \){req.url}`);
  next();
});

Logs every incoming request.


b) Authentication

function auth(req, res, next) {
  const isLoggedIn = true;

  if (!isLoggedIn) {
    return res.status(401).send('Unauthorized');
  }

  next();
}

app.get('/profile', auth, (req, res) => {
  res.send('Protected profile');
});

Only allows access if the user is authenticated.


c) Request Validation

app.post('/user', (req, res, next) => {
  if (!req.body.name) {
    return res.status(400).send('Name is required');
  }
  next();
}, (req, res) => {
  res.send('User created');
});

Ensures correct data before processing.


Final Understanding

  • Middleware is a function that runs between request and response

  • It sits in the request lifecycle before the final handler

  • There are different types: application-level, router-level, and built-in

  • Middleware executes in order

  • next() controls the flow

  • It is used for logging, authentication, validation, and more


Summary

Middleware is the backbone of Express applications. It allows you to break down request handling into small, reusable steps that process data, enforce rules, and control application flow. By chaining middleware functions together, you can build scalable and maintainable systems. Whether it is logging requests, checking authentication, or validating input, middleware gives you full control over how your application behaves at every stage of a request.