Express 路由導向:解析 Path Params 與 Query String

網頁伺服器的核心工作就是「根據不同的網址 (URL) 與 HTTP 方法,回傳正確的內容」。Express 提供了一套極其強大且直覺的路由 (Routing) 機制,讓你輕鬆管理複雜的 API 路徑。

基礎路由語法

一個路由定義由:實例 (app)HTTP 方法路徑 (Path)處理器 (Handler) 組成。

app.get('/about', (req, res) => {
  res.send('關於我們頁面');
});

app.post('/login', (req, res) => {
  res.send('處理登入邏輯');
});

獲取動態參數 (Path Parameters)

當網址中包含變動的部分(例如使用者的 ID),我們使用冒號 : 來定義變數。

// 匹配 /users/123 或 /users/mike
app.get('/users/:userId/books/:bookId', (req, res) => {
  // 參數會自動解析並存放在 req.params 物件中
  const { userId, bookId } = req.params;
  res.send(`正在查詢使用者 ${userId} 的書籍編號:${bookId}`);
});

處理查詢字串 (Query String)

查詢字串通常位於網址末端 ? 之後。這不需要在路由中特別定義,Express 會自動解析。

// 請求網址:/search?q=iphone&limit=10
app.get('/search', (req, res) => {
  const { q, limit } = req.query; // 獲取參數
  res.json({ resultsFor: q, pageSize: limit });
});

路由模組化:express.Router

當專案規模擴大時,將所有路由塞在 app.js 會變得雜亂無章。我們可以使用 express.Router 將路由拆分到獨立的檔案中。

步驟 1:建立路由模組 routes/products.js

const express = require('express');
const router = express.Router();

router.get('/', (req, res) => res.send('產品列表'));
router.get('/:id', (req, res) => res.send(`產品詳情:${req.params.id}`));

module.exports = router;

步驟 2:在主程式中掛載

const productRouter = require('./routes/products');

// 設定統一的前綴路徑
app.use('/api/products', productRouter);
// 最終網址:/api/products/ 或 /api/products/123

路由匹配優先權 (Route Priority)

Express 的路由匹配是 「由上而下」 的。請務必注意定義的順序:

// 正確:先定義特定的路徑
app.get('/users/admin', (req, res) => { ... });

// 再定義模糊匹配的路徑
app.get('/users/:id', (req, res) => { ... });

如果順序對調,當使用者造訪 /users/admin 時,會觸發 /:id 路由,並將 id 解析為 "admin"

404 頁面處理:通常會在所有路由定義的最末端,掛載一個捕捉所有路徑 (Catch-all) 的處理器來回應 404 錯誤。

總結

  1. req.params 用於獲取路徑中的變數。
  2. req.query 用於獲取網址末端的查詢參數。
  3. 善用 express.Router 將程式碼按功能模組化,是專業開發的必經之路。