API Gateway 微服務閘道設計模式教學:路由、聚合、鑑權一次搞懂
微服務架構最常被忽略的一塊就是 API Gateway。很多團隊把服務拆得很細,但沒有統一的入口來管理,結果前端要呼叫十幾個不同的 API endpoint,每個都要處理認證、錯誤處理——簡直是惡夢。今天就來把 API Gateway 的三大設計模式講清楚。
為什麼需要 API Gateway?
API Gateway 的角色就像微服務架構的「大門管家」。所有外部請求都先經過它,再被路由到對應的內部服務。核心職責包括:
- 統一入口:前端只需要知道一個 URL
- 路由分發:把請求轉到對應的微服務
- 鑑權認證:集中處理身份驗證
- 限流與監控:保護後端服務不被打爆
- 協議轉換:外部 HTTPS,內部可以用 gRPC
沒有閘道時的痛點
在我之前待的公司,一開始就是讓前端直接呼叫各個微服務。結果:
- 緊耦合:前端要知道每個服務的地址和 API 格式
- 重複工作:每個服務都要自己處理 JWT 驗證、CORS、限流
- 安全風險:所有服務都直接暴露在外
- 效能問題:一個頁面要打 5-6 個 API 才能載入完
如果你之前看過我寫的 OAuth 2.0 第三方登入教學,就知道光是認證這件事就很複雜了。讓每個微服務都自己處理,維護成本超高。
設計模式一:閘道路由(Gateway Routing)
最基本的模式:API Gateway 作為反向代理,根據 URL path 把請求路由到不同的服務。
# Nginx 簡易路由設定範例
upstream user_service {
server user-svc:3001;
}
upstream order_service {
server order-svc:3002;
}
upstream product_service {
server product-svc:3003;
}
server {
listen 80;
location /api/users {
proxy_pass http://user_service;
}
location /api/orders {
proxy_pass http://order_service;
}
location /api/products {
proxy_pass http://product_service;
}
}
這個模式的好處是簡單直觀:前端只需要知道 api.example.com,不需要知道後面有幾個服務。
設計模式二:閘道聚合(Gateway Aggregation)
當一個頁面需要從多個服務取資料時,不要讓前端打 5 個 API——讓 Gateway 幫你聚合:
// Gateway 聚合端點範例
app.get('/api/dashboard', async (req, res) => {
const [user, orders, notifications] = await Promise.all([
fetch('http://user-svc:3001/profile'),
fetch('http://order-svc:3002/recent'),
fetch('http://notification-svc:3004/unread')
]);
res.json({
user: await user.json(),
recentOrders: await orders.json(),
notifications: await notifications.json()
});
});
聚合模式的最大好處是減少「聊天式」的 API 呼叫。前端原本要打 3 個請求,現在只要 1 個。對行動端特別重要——手機網路延遲高,每少一個請求就快一截。
設計模式三:閘道卸載(Gateway Offloading)
把那些「每個服務都要做的事」集中到 Gateway 處理:
- SSL 終止:外部 HTTPS 到 Gateway,內部用 HTTP
- 身份驗證:在 Gateway 統一驗 JWT token
- 限流:統一的速率限制
- 日誌記錄:集中的 access log
- CORS 處理:統一設定跨域規則
// Express middleware:在 Gateway 集中驗證 JWT
const jwt = require('jsonwebtoken');
function authMiddleware(req, res, next) {
const token = req.headers.authorization?.replace('Bearer ', '');
if (!token) return res.status(401).json({ error: 'No token' });
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = decoded;
req.headers['x-user-id'] = decoded.userId;
req.headers['x-user-role'] = decoded.role;
next();
} catch (err) {
res.status(401).json({ error: 'Invalid token' });
}
}
app.use('/api', authMiddleware);
這樣下游的微服務就不用自己驗 JWT 了,直接信任 Gateway 傳來的 header。
進階:BFF 模式(Backend for Frontend)
當你的系統同時服務 Web、Mobile、IoT 等不同客戶端時,一個 Gateway 可能不夠。BFF 模式建議為每種客戶端打造專屬的後端:
- Web BFF:回傳完整資料,支援 SSR
- Mobile BFF:回傳精簡資料,減少傳輸量
- IoT BFF:支援 MQTT 協議
每個 BFF 本身就是一個小型 Gateway,只暴露該客戶端需要的 API。
工具比較:Kong vs Nginx vs 雲端方案
| 特性 | Kong | Nginx | AWS API Gateway |
|---|---|---|---|
| 類型 | 專用 API Gateway | 通用反向代理 | 雲端託管 |
| 設定方式 | Admin API + GUI | 設定檔 | Web Console |
| 外掛生態 | 豐富 | 需自行設定 | AWS 整合 |
| 學習曲線 | 中等 | 低 | 低(但綁 AWS) |
| 成本 | 開源免費 / 企業版付費 | 免費 | 按請求量計費 |
我的建議:小團隊先用 Nginx 搭配手寫 middleware。規模變大再考慮 Kong。全上雲就用雲端服務商的 API Gateway。
實戰:用 Express + http-proxy 打造簡易閘道
對於中小型專案,用 Node.js 手刻一個閘道不難。搭配 GitHub Actions CI/CD 自動部署更方便:
const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');
const rateLimit = require('express-rate-limit');
const app = express();
// 集中鑑權
app.use('/api', authMiddleware);
// 限流
app.use(rateLimit({ windowMs: 60000, max: 100 }));
// 路由到各微服務
app.use('/api/users', createProxyMiddleware({
target: 'http://user-svc:3001',
changeOrigin: true,
pathRewrite: { '^/api/users': '' }
}));
app.use('/api/orders', createProxyMiddleware({
target: 'http://order-svc:3002',
changeOrigin: true,
pathRewrite: { '^/api/orders': '' }
}));
// 聚合端點
app.get('/api/dashboard', async (req, res) => {
// 聚合邏輯...
});
app.listen(8080);
結語
API Gateway 不是可選的——只要你在做微服務,就需要一個統一入口。三大設計模式各有用途:
- 路由:最基礎,解耦前後端
- 聚合:減少網路往返,提升效能
- 卸載:集中處理橫切關注點
如果你正在從單體架構遷移到微服務,Gateway 是第一個要建好的基礎設施。搭配 PostgreSQL 效能優化和好的 CI/CD 流程,整個後端架構就穩了。
繼續閱讀
微服務架構入門教學:從單體式到微服務的拆分策略與實戰指南
相關文章
你可能也喜歡
探索其他領域的精選好文