← Node / Backend Course

NODE / BACKEND CORE · 103

Native HTTP Server:不用框架先看 Request 怎麼進 Process

Express 會幫你包很多便利功能。先用 Node 內建 http module 看一次底層 request/response callback,你才知道 framework 到底抽象了什麼。

Learning outcomes

1. 最小 server

import http
  from "node:http";

const server =
  http.createServer(
    (req, res) => {
      res.statusCode = 200;
      res.setHeader(
        "Content-Type",
        "application/json"
      );

      res.end(
        JSON.stringify({
          ok: true
        })
      );
    }
  );

server.listen(
  3000,
  "127.0.0.1"
);

2. 時間順序

node server.js→ processlisten :3000等待request arrivescallbackresponse

createServer 時 callback 不會立刻代表有 request;它是之後事件發生時才被 Node 呼叫。

3. req / res 是這次 request 的 runtime objects

console.log(
  req.method,
  req.url,
  req.headers
);

每個 HTTP request 都會有自己的 request/response context。

4. Request body 是 stream

let body = "";

for await (
  const chunk of req
) {
  body += chunk;
}

不是所有 body 都一次完整躺在 memory 裡等你讀。Express 的 express.json() 之後會幫你處理常見 JSON body parsing。

5. 手動 route 一次

if (
  req.method === "GET"
  && req.url === "/courses"
) {
  res.statusCode = 200;
  res.end(
    JSON.stringify(
      await loadCourses()
    )
  );
  return;
}

res.statusCode = 404;
res.end(
  JSON.stringify({
    error: "not found"
  })
);

你會立刻感受到 framework 為什麼需要 routing abstraction。

6. bind address

server.listen(
  3000,
  "127.0.0.1"
);

這只接受 local interface 的連線。改成 0.0.0.0 代表 listen 所有 IPv4 interfaces,但外網是否可達仍還有 firewall/security group/reverse proxy 等層。

Project checkpoint:Course API v3

GET /health
→ 200 { ok: true }

GET /courses
→ 200 [...]

anything else
→ 404

現在真的有 server;下一課用 Express 把手寫 routing/body parsing 抽象掉。

Debug evidence

ss -lntp
curl -i http://127.0.0.1:3000/health

如果 local curl 都失敗,就先不要查 DNS / Cloudflare。先確認 process 與 listener。

Knowledge check

  1. request callback 是什麼時候被呼叫?
  2. listener 127.0.0.1 和 0.0.0.0 差在哪?
  3. 為什麼「server started」不代表 Internet 一定可達?
  4. 自己加一條 GET /courses/:id,體會原生 routing 的麻煩。