← Node / Backend Course

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

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

  1. 實際 method/path 是什麼?
  2. 前面的 middleware 有沒有提早 response?
  3. 有沒有忘記 next()?
  4. route 註冊順序是否被 catch-all 吃掉?

Knowledge check

  1. Express app 還是不是 Node process?
  2. next() 真正交給誰?
  3. 為何 middleware order 會改變行為?
  4. 加 request id middleware,讓 error log 也能印出 id。