Node.jsadvanced 9 min
Functions that sit between a request and a response: logging, authentication checks and error handling.
What middleware is, how next() passes control along, how to protect routes, and how a dedicated error handler works in Express.
Many tasks apply to lots of routes: logging, checking a login, parsing bodies, limiting traffic. Middleware lets you write each once and plug it in wherever it is needed, instead of repeating it in every route.
Middleware is a function that receives (req, res, next). It can read or change the request, end the response, or call next() to pass control to the next function in the chain.
Order matters: middleware and routes run in the order you register them.
app.use(fn) applies to all routes after it.app.get("/admin", checkAdmin, handler).next()) can reject a request, for example with 401 Unauthorized.(err, req, res, next), and is registered last. Express sends any error thrown in a route to it.logger runs for every request, prints it and calls next()./public has no extra middleware, so anyone gets through./private has requireKey in front of its handler. Without the x-api-key: secret header, it replies 401 and never reaches the handler./boom throws. Express passes the error to the four-argument handler registered last, which logs it and answers 500.This script starts the server and calls it as a client, so you can see each result. Save as mw.mjs, run npm install express and node mw.mjs.
next(), so the request hangs.next() after sending a response, which causes an error.(req, res, next) and calls next() to continue.Next: storing data in a database.
function logger(req, res, next) {
console.log(req.method, req.url);
next();
}
app.use(logger); // runs for every requestimport express from "express";
const app = express();
function logger(req, res, next) {
console.log("request:", req.method, req.url);
next();
}
function requireKey(req, res, next) {
if (req.get("x-api-key") !== "secret") {
return res.status(401).json({ error: "Unauthorized" });
}
next();
}
app.use(logger);
app.get("/public", (req, res) => res.send("Anyone can see this"));
app.get("/private", requireKey, (req, res) => res.send("Secret data"));
app.get("/boom", () => {
throw new Error("Something broke");
});
app.use((err, req, res, next) => {
console.log("error handler:", err.message);
res.status(500).json({ error: "Server error" });
});
app.listen(3000);