NODE / BACKEND CORE · 104
Express Routing / Middleware:把 Request 變成可追蹤 Pipeline
Express 沒有取代 Node HTTP server;它在 Node runtime 上提供 routing、body parsing、middleware composition 等 abstraction。真正要學的是 request 穿過 pipeline 的順序。
Learning outcomes
- 能追蹤 middleware execution order。
- 能說明 route = method + path + handler。
- 能判斷何時
next()、何時直接 response。 - 能建立 request id / logging middleware。
1. 最小 Express app
import express
from "express";
const app = express();
app.use(
express.json()
);
app.get(
"/health",
(req, res) => {
res.json({
ok: true
});
}
);
app.listen(3000);2. Route 是 method + path
app.get(
"/courses",
listCourses
);
app.get(
"/courses/:id",
getCourse
);
app.post(
"/courses",
createCourse
);GET /courses 和 POST /courses 是不同 route contract。
3. Middleware execution order
app.use(requestId);
app.use(logger);
app.use(express.json());
app.use(requireUser);
app.post(
"/courses",
createCourse
);
requestrequestIdloggerjson parserauthrouteresponse
4. next() 不是「繼續 JavaScript 下一行」
function logger(
req,
res,
next
) {
console.log(
req.method,
req.url
);
next();
}next() 交給下一個 matching middleware / route。若你已經送出 response,通常不應再讓 pipeline 繼續寫第二次 response。
5. Request ID:把跨層 evidence 串起來
function requestId(
req,
res,
next
) {
req.id =
crypto.randomUUID();
res.set(
"x-request-id",
req.id
);
next();
}之後 log、DB operation、external API call 都可以帶同一個 request id。
6. Project checkpoint:Course API v4
app.use(requestId);
app.use(logger);
app.use(express.json());
app.get(
"/courses",
listCourses
);
app.get(
"/courses/:id",
getCourse
);
app.post(
"/courses",
createCourse
);
app.use(notFound);
app.use(errorHandler);這已經形成明確 pipeline;下一課加入 trust boundary:validation、authentication、authorization。
Debug evidence:route 沒進 handler
- 實際 method/path 是什麼?
- 前面的 middleware 有沒有提早 response?
- 有沒有忘記
next()? - route 註冊順序是否被 catch-all 吃掉?
Knowledge check
- Express app 還是不是 Node process?
next()真正交給誰?- 為何 middleware order 會改變行為?
- 加 request id middleware,讓 error log 也能印出 id。