Node.js · 14/19 6 min
Express routing traps
Route order, params vs literals, Router mount paths, and middleware that runs for the wrong routes.
First match wins
router.get("/:id", getOne); // ❌ "/stats" is captured as id = "stats"
router.get("/stats", getStats); // never reached
router.get("/stats", getStats); // ✅ literals before params
router.get("/:id", getOne);
Mount paths are stripped
app.use("/api/orders", ordersRouter);
// inside ordersRouter the path is relative:
router.get("/", list); // GET /api/orders
router.get("/orders", list); // ❌ this is /api/orders/orders
A 404 from a test that "obviously" has a route is almost always a doubled or missing prefix.
Params
req.params.idis a string. Compare with===against a number and it never matches.- Param names must match:
/:userIdisreq.params.userId, notreq.params.id. - A Router that needs the parent's params needs
express.Router({ mergeParams: true }).
Middleware scope
app.use(requireAuth); // every route BELOW this line, including public ones
app.post("/login", login); // ❌ now login needs a token
app.post("/login", login); // ✅ public routes first
app.use("/api", requireAuth, api); // or scope it to a mount
Methods
app.getwon't answer aPOST. A 404 on the right path often means the wrong verb.PUTreplaces,PATCHupdates fields. Tests forPATCHexpect untouched fields to survive.DELETEthat succeeds with no body is 204; don't callres.jsonafterres.status(204).
Order inside app.js
- body parsers (
express.json()), CORS, logging - public routes
- auth, then protected routes
- 404 handler
- error handler (four arguments)
Practise it now
Next in Node.js
Config and environment variables