The Pipeline Every Request Flows Through
Middleware
Middleware functions run before (and around) your handlers. Auth, logging, body parsing — all middleware.
What you'll learn
- Author a middleware function
- Chain them with app.use
- Mount per-route or globally
A middleware is a function (req, res, next) => { ... } that
runs in a chain. Each one either calls next() to pass to the
next middleware, or sends a response and stops the chain.
Anatomy
function logger(req, res, next) {
console.log(`${req.method} ${req.url}`);
next();
}
app.use(logger); app.use(fn) runs fn before every route handler.
Order Matters — A Lot
app.use(logger);
app.use(requireAuth);
app.use(parseBody);
app.get("/api/users", listUsers); Logger runs first, then auth, then body parsing, then the route handler. Reverse them at your peril.
Built-in Middleware
import express from "express";
const app = express();
app.use(express.json()); // parse JSON bodies
app.use(express.urlencoded({ extended: true })); // form bodies
app.use(express.static("public")); // serve files express.json() populates req.body for Content-Type: application/json.
Per-Route Middleware
app.get("/admin", requireAdmin, listAdmins);
// Multiple:
app.post("/api/orders", requireAuth, validateOrder, createOrder); Middleware between the path and the final handler runs in order for that route only.
A Real-World Auth Middleware
function requireAuth(req, res, next) {
const token = req.headers.authorization?.replace("Bearer ", "");
if (!token) {
return res.status(401).json({ error: "missing token" });
}
try {
req.user = verifyToken(token);
next();
} catch {
res.status(401).json({ error: "invalid token" });
}
}
app.get("/me", requireAuth, (req, res) => res.json(req.user)); Note: send a response or call next(). Never both.
Error-Handling Middleware
Four args, special signature:
app.use((err, req, res, next) => {
console.error(err);
res.status(500).json({ error: "internal" });
}); Mount it last. Errors thrown by handlers (or passed via
next(err)) land here.
Popular Middleware Packages
| Package | Purpose |
|---|---|
cors | CORS headers |
helmet | Security headers |
morgan | Request logging |
compression | gzip / brotli |
cookie-parser | Parse cookies |
express-rate-limit | Throttle requests |
Each app.use(packageName()) and you’re set.