Node.jsExpress後端開發JavaScript前端工程師前端教學

Node.js 原生 HTTP 到 Express 入門:前端工程師後端指南

前端工程師學後端?從 Node.js 原生 HTTP 模組開始,理解 Express 框架底層邏輯。含完整程式碼範例,幫助你快速掌握後端開發思維。

· 6 分鐘閱讀

學會 React 之後,開始碰後端,卻發現一堆名詞完全陌生?Express、Koa、Hapi——這些框架到底在幫你做什麼?這篇文章從 Node.js 原生 HTTP 模組說起,讓你真正理解「框架」解決的問題,而不是只會跟著範例寫 code。


前言:為什麼要從原生開始?

多數前端工程師接觸後端,都是從 Express 開始的。跟著網路教學裝好框架、寫幾個路由,伺服器就跑起來了——但卻很難回答這個問題:「如果沒有 Express,這段程式碼會長什麼樣?」

這個問題重要,不是因為你要自己寫 HTTP 伺服器(你不会真的需要),而是因為:

  • 除錯時離不開框架:錯誤訊息最終還是要回到原生 HTTP 的層次才能理解
  • 理解框架的限制:知道邊界在哪裡,才知道什麼時候該繞路
  • 快速掌握其他框架:Koa、Fastify、Hapi——這些框架解決的是同一組問題,只是做法不同

所以在學 Express 之前,先用 Node.js 原生 HTTP 模組寫一個最簡單的伺服器。


用原生 HTTP 模組寫一個伺服器

Node.js 有一個內建的 http 模組,不需要安裝任何套件就能用。

// server-native.mjs
import http from 'node:http';

// 建立 HTTP 伺服器
const server = http.createServer((req, res) => {
  // req 是 incoming message,res 是 server response
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('Hello, 您好!');
});

// 監聽 3000 port
server.listen(3000, () => {
  console.log('Server running at http://localhost:3000/');
});

執行 node server-native.mjs,用瀏覽器打開 http://localhost:3000,就能看到「Hello, 您好!」。

但這個伺服器有幾個問題:

  1. 所有 request 都回傳同樣的內容——不管是 //about、還是 /api/users,都回傳「Hello」
  2. 沒有路由概念——需要自己判斷 req.url 是什麼
  3. 回傳的都是純文字——如果要回 JSON,需要自己序列化的邏輯

讓我們把路由處理加進去:

// server-with-router.mjs
import http from 'node:http';

const server = http.createServer((req, res) => {
  const { method, url } = req;

  // 簡單的路由判斷
  if (url === '/api/users' && method === 'GET') {
    const users = [
      { id: 1, name: '小明', role: 'admin' },
      { id: 2, name: '大華', role: 'user' },
    ];
    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify(users));

  } else if (url === '/api/users' && method === 'POST') {
    // POST 處理需要讀取 request body,稍後再說
    res.writeHead(201, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify({ message: 'Created!' }));

  } else {
    res.writeHead(404, { 'Content-Type': 'text/plain' });
    res.end('Not Found');
  }
});

server.listen(3000, () => {
  console.log('Server running at http://localhost:3000/');
});

這樣就有了基本的路由——但你應該能感受到,光是「GET/POST 路由」這件事,就已經需要一堆 if/else 判斷了。如果再加上路徑參數(/api/users/:id)、查詢參數(?page=1)、錯誤處理、CORS 設定——這些基礎建設會佔掉你大部分的精力,而不是放在真正的業務邏輯上。

這就是 Express 存在的理由。


Express 登場:框架解決了什麼?

Express 的核心貢獻,是把 HTTP 處理的基礎建設抽象掉,讓你只專心在「收到什麼 request、回什麼 response」這件事上。

同樣的路由,用 Express 寫:

// server-express.mjs
import express from 'express';

const app = express();

// GET /api/users — 取得使用者列表
app.get('/api/users', (req, res) => {
  const users = [
    { id: 1, name: '小明', role: 'admin' },
    { id: 2, name: '大華', role: 'user' },
  ];
  res.json(users);  // Express 自動幫你設定 Content-Type + JSON 序列化
});

// POST /api/users — 新增使用者
app.post('/api/users', (req, res) => {
  const newUser = req.body;  // Express 幫你解析 JSON body
  // 實際應用會把 newUser 存進資料庫
  res.status(201).json({ message: 'Created!', user: newUser });
});

// 404 處理
app.use((req, res) => {
  res.status(404).json({ error: 'Not Found' });
});

app.listen(3000, () => {
  console.log('Express server on http://localhost:3000');
});

看出差別了嗎?用原生 HTTP,你需要自己判斷 method 和 url、自己設定 header、自己序列化 JSON。用 Express,這些全部幫你處理好,你只需要專心寫業務邏輯。

Express 實際幫你省掉的幾件事

處理的問題原生 HTTPExpress
路由 matching手動 if/elseapp.get(), app.post()
路徑參數字串解析req.params.id
Query 參數URL parsingreq.query.page
Request body 解析stream 讀取express.json() middleware
JSON 回應手動 JSON.stringify + headerres.json()
404 處理手動 else branchapp.use() 最後層
CORS 設定手動設定 headercors middleware
錯誤處理try/catch 到處寫app.use((err, req, res, next) => {})

Middleware 是 Express 最核心的概念。簡單來說,middleware 就是在請求和回應之間的「關卡」,每個關卡都可以對 request 或 response 做事情:

import express from 'express';
import cors from 'cors';

const app = express();

// Middleware 1:解析 JSON body
app.use(express.json());

// Middleware 2:處理 CORS
app.use(cors());

// Middleware 3:自己寫的 logging middleware
app.use((req, res, next) => {
  const start = Date.now();
  res.on('finish', () => {
    const duration = Date.now() - start;
    console.log(`${req.method} ${req.url} — ${res.statusCode} (${duration}ms)`);
  });
  next();  // 必須 call next() 才會進入下一個 middleware
});

// 路由
app.get('/api/users', (req, res) => {
  res.json([{ id: 1, name: '小明' }]);
});

app.listen(3000);

Middleware 的順序很重要。Express 會由上往下依序執行每個 middleware,所以 express.json() 必須在最前面——否則你的路由 handler 收到 req.body 時會是 undefined。


前端視角:思維的轉變

對前端工程師來說,最大的認知轉換不是語法,而是**「誰觸發什麼」**。

前端:事件驅動 UI

前端的世界是由事件驅動的——使用者點擊按鈕、填寫表單、滾動頁面,這些事件觸發了你的程式碼

// 前端:等待事件
const handleSubmit = async (formData) => {
  const response = await fetch('/api/users', {
    method: 'POST',
    body: JSON.stringify(formData),
  });
  const result = await response.json();
  setUser(result);
};

後端:等待請求

後端伺服器的角色是被動等待——不知道什麼時候會有請求,不知道是誰發的,不知道裡面裝什麼。你能做的,是把「收到什麼請求 → 回什麼回應」這件事定義清楚。

// 後端:定義「收到什麼請求時該怎麼處理」
app.post('/api/users', async (req, res) => {
  // req.body 裡有前端送來的資料
  const { name, email } = req.body;

  // 這裡會是資料庫操作、驗證、商業邏輯
  const newUser = await db.users.create({ name, email });

  // 回應
  res.status(201).json(newUser);
});

這個「等待 → 處理 → 回應」的迴圈,就是 HTTP 伺服器的本質。Express 把這個迴圈寫得更好寫、更好維護,但底層運作的还是同一套邏輯。


常見問題

Q:Express 跟 Fastify、Koa 比起來怎麼選?

A:如果是剛開始學後端,Express 仍然是最好的選擇——生態最大、資源最多、多數時候面試問的也是 Express。Fastify 在效能上更好,但社群資源較少。Koa 是 Express 原作者後來做的,概念更乾淨,但需要自己組合 middleware(沒有 express.json() 這種內建的)。建議先熟悉 Express,再去看其他框架感受差異。

Q:需要學 TypeScript 嗎?

A:需要。Express 本身是 JavaScript,但現代後端開發幾乎都是 TypeScript。用 TypeScript 寫 Express 不只是「加型別」,而是讓你對於 request/response 的結構有更清晰的認知,對除錯和重構都有幫助。

Q:Express 適合多大的專案?

A:Express 本身很輕量,適合中小型專案。但它不強迫你用特定的架構,所以大了之後容易變成「義大利麵」。如果專案規模變大,建議用 TypeScript + 一致的資料夾結構(controller/service/repository 分層),不要把所有邏輯都寫在路由 handler 裡。


總結:框架讓你站在巨人的肩膀上

這篇文章的核心概念只有一個:框架解決的是 HTTP 處理的基礎建設,讓你專心在業務邏輯

從原生 HTTP 到 Express,你學到的不是「怎麼用 Express」,而是:

  • HTTP 伺服器的本質是什麼
  • 路由、Middleware、request/response 這些概念從哪裡來
  • 框架幫你省掉了什麼、隱藏了什麼

理解這些之後,你對後端的恐懼感會大幅降低,無論未來要用 Express、Koa 還是 Fastify,都能快速上手。

下一步,可以試著把 Express 加上資料庫(SQLite 是最簡單的起點),做一個完整的 CRUD API出來——那才是真正「後端思維」開始形成的時刻。


想了解 Node.js 2026 年的版本選擇,可參考 《Node.js 22 vs 24》,裡面有 LTS 選擇和原生功能更新的完整整理。