Routing and Middleware
Route parameters, JSON bodies, and the middleware pipeline.
What you will learn
- Read params, query and body
- Write middleware
- Use routers
Two ideas sit at the heart of Express: routing (which code handles which request) and middleware (a pipeline every request passes through).
app.use(express.json()); // parse JSON bodies
app.get("/users/:id", (req, res) => {
res.json({ id: req.params.id, verbose: req.query.verbose }); // /users/7?verbose=1
});
app.post("/users", (req, res) => {
const { name, email } = req.body;
res.status(201).json({ name, email });
});req.params: values from the path (:id).req.query: the query string (?page=2).req.body: parsed body; requires theexpress.json()middleware, otherwise it is undefined.req.headers: request headers.
Middleware
A middleware function receives (req, res, next). It can inspect or change the request, end the response, or call next() to pass control on. They run in the order you register them.
function logger(req, res, next) {
const start = Date.now();
res.on("finish", () => {
console.log(`${req.method} ${req.url} ${res.statusCode} ${Date.now() - start}ms`);
});
next();
}
function requireKey(req, res, next) {
if (req.get("x-api-key") !== "secret") {
return res.status(401).json({ error: "Unauthorized" });
}
next();
}
app.use(logger); // for every route
app.get("/private", requireKey, (req, res) => res.json({ ok: true })); // for one routeOrder matters
Register express.json() and your logger before the routes that need them. Forgetting next() leaves the request hanging.
Routers
Split a large app into modules with express.Router().
// routes/users.js
import { Router } from "express";
const router = Router();
router.get("/", (req, res) => res.json([]));
router.get("/:id", (req, res) => res.json({ id: req.params.id }));
export default router;
// index.js
import users from "./routes/users.js";
app.use("/api/users", users);Useful built-in and third-party middleware
express.static("public"): serve files from a folder.cors: allow browsers on other origins to call your API.helmet: set secure HTTP headers.morgan: ready-made request logging.
Try it yourself
Write middleware that adds a req.requestId (a random id) and an X-Request-Id response header, and apply it to all routes.
Show solution
import { randomUUID } from "node:crypto";
app.use((req, res, next) => {
req.requestId = randomUUID();
res.setHeader("X-Request-Id", req.requestId);
next();
});