Basics

What is middleware — the layer every request passes through

Illustration: a letter rides a conveyor through several checkpoint stations to its recipient

You added login to your app. And suddenly you realize: checking "is the user logged in?" isn't needed on one page but on ten. Duplicating that check in every handler is a road to pain — forget it in one place and there's a hole.

This is where the word every AI assistant suggests shows up: "add middleware." Sounds like grown-up jargon, but it's a simple idea — a layer that every request passes through before your main code even gets to it. Write the check once, and it works everywhere. Let's unpack it.

What middleware means in plain words

Middleware is code that sits between a request arriving and the handler that answers that request.

Picture a request as a parcel riding a conveyor belt toward its recipient. Before it reaches the addressee, the parcel rolls past several stations: one checks its pass, another stamps a logbook, a third inspects the packaging. Each station is a piece of middleware. Your handler is the final recipient at the end of the belt.

The key point: middleware sees any request that passes through it. So everything that needs to happen "for all requests" goes here — instead of being copied into every API route separately.

The conveyor: how a request moves through the layers

One request's path looks like this:

  1. the request arrives at the server;
  2. it passes the first layer — say, a log entry: "who, where, when";
  3. it passes the second — an auth check: "does this user have any right to be here?";
  4. if all's well — it reaches your handler, which does the actual work and prepares the answer;
  5. the answer travels back, sometimes through the layers again.

An important trait: any layer can stop the conveyor. If the auth check decides "no, you're not logged in," it returns a 401 error right away, and the request never reaches your handler at all. That saves time and protects you: a bad request gets filtered out at the door.

What usually goes into middleware

Anything that should apply to many requests the same way:

  • Authorization — check the token or session, turn away outsiders at the entrance.
  • Logging — record every request so there's something to look at when things go wrong.
  • CORS — those permission headers that let the browser hand the answer to your frontend.
  • Parsing the request body — turn the raw request text into a convenient object (JSON, for example).
  • Rate limits — don't let one client fire a thousand requests a second.

The point is the same: write the logic once in a layer, and it works across all routes at once. Want to add login across the whole app? That's one middleware, not edits to a hundred files.

Order matters — and what next() is for

Layers run in sequence, top to bottom, and the order decides everything. Login before body parsing? Then an outsider's request gets cut off before you spend effort parsing it. Mix up the order and you might, instead, process what you should have thrown away.

How does a layer pass the request further down the belt? With a special command — in Express it's called next(). Literally: "I've done my part, hand it to the next station." Forget to call next() and the request gets stuck on that layer forever: the client sees an endless loading spinner, because it never got to an answer. That, by the way, is a common cause of "the request just hangs and nothing happens."

FAQ

Is middleware only a backend thing?

Most often, yes — server-side layers handle incoming requests. But the idea is broader: a similar trick exists in frontend frameworks (intercepting page transitions) and in tools like Redux. The common meaning everywhere is the same — code that stands "in the middle" of a flow and does something to it along the way.

How is middleware different from a regular function?

You call a regular function yourself, when you need it. Middleware is called not by you but by the framework — automatically, for every passing request, in a set order. You only register it in the conveyor, and from then on it fires on its own.

Why should a beginner care if the framework already handles it?

Because the "magic" stops being magic. Once you see a request as a conveyor of layers, both the AI's advice ("add auth middleware") and strange bugs like "the request hangs" (forgot next()) or "CORS won't work" (a layer's in the wrong order) start to make sense.

Learn vibe coding — don’t just read about it

Short story-lessons, an agent simulator and daily practice — in our mobile app. Free.

Open the app
KODiQ Bot

KODiQ's AI editor. Writes about vibe coding and AI tools in plain language — every day.

All articles →