Chapter 47: Node.js Middleware

Step 1 – What is Middleware? (the clearest explanation)

Middleware is a function that has access to the request object (req), response object (res), and the next middleware function in the application’s request-response cycle.

It sits between the incoming request and your final route handler.

Think of middleware as a chain of people passing a parcel:

  • The request comes in (parcel arrives at the first person)
  • Each middleware can:
    • Look at the parcel (read req)
    • Modify the parcel (change req.body, req.user, add headers…)
    • Reject the parcel (send error response and stop)
    • Pass the parcel to the next person (next())
    • End the delivery (send response and stop chain)

Middleware runs in the order you write it.

Step 2 – Basic types of middleware in Express

There are four main places you can use middleware:

Type Syntax example When it runs Typical use case
Application-level app.use(middleware) For every request CORS, logging, helmet, body-parser, auth globally
Router-level router.use(middleware) For routes under this router Authentication for /api/admin/* routes
Route-specific app.get(‘/users’, middleware, handler) Only for this exact route Validate ID before getting user
Error-handling app.use((err, req, res, next) => { … }) Only when an error occurs (4 arguments) Global error formatting, logging

Golden rule:

Middleware is executed sequentially — once next() is called, it moves to the next middleware. If no next() is called and no response is sent → the request hangs forever (very common bug).

Step 3 – Project setup (realistic modern Express + TypeScript)

Bash

tsconfig.json

JSON

package.json scripts

JSON

Step 4 – Creating our first middleware (logging middleware)

src/middleware/logger.middleware.ts

TypeScript

Using it globally

TypeScript

What you see in terminal when you visit http://localhost:3000

text

Step 5 – Built-in middleware (you use them every day)

Express ships with several built-in middleware functions:

TypeScript

Realistic usage

TypeScript

Step 6 – Custom middleware types – real production examples

6.1 Authentication middleware (most common use case)

TypeScript

Using it

TypeScript

6.2 Input validation middleware (using Zod)

TypeScript

Usage

TypeScript

6.3 Rate limiting middleware (protect against abuse)

TypeScript

6.4 Error-handling middleware (must be last)

TypeScript

Important order rule

Middleware is executed in the order you write it:

  1. Global middleware (helmet, cors, compression, logger)
  2. Body parsers (express.json())
  3. Custom middleware (auth, validation)
  4. Routes
  5. Error handler (last!)

Step 7 – Complete realistic example (small but production-like)

src/index.ts (putting it all together)

TypeScript

Summary – Middleware in Express (2025–2026 reality)

Middleware type Where to place it Typical examples Must-have in production?
Global app.use() (top) helmet, cors, compression, body-parser, logger Yes
Authentication Before protected routes JWT verify, role check Yes (if you have auth)
Validation Before controller Zod, express-validator Yes
Rate limiting On API routes express-rate-limit Yes (public APIs)
Error handling Last in the chain Custom error handler Yes (must-have)
Logging Early in the chain morgan, pino, winston Yes

Golden middleware order (most common real apps)

TypeScript

Which part of middleware would you like to go much deeper into next?

  • Full authentication middleware (JWT + role-based access)
  • Rate limiting strategies (global, per-route, per-user)
  • Advanced logging with Pino + correlation IDs
  • Request validation with Zod + custom error messages
  • Middleware performance & order optimization
  • Testing middleware with Jest/Vitest

Just tell me what you want to focus on — I’ll continue with complete, production-ready code and explanations. 😊

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *