跳至主要内容

Mock API 整合策略

本文解釋 AppFuse Web 的 Mock API 設計理念和使用策略。

為什麼需要 Mock API?

傳統開發的問題

前端開發 ──等待──> 後端 API 完成 ──等待──> 整合測試

開發延遲

前後端緊密耦合導致:

  1. 開發阻塞:前端必須等待後端 API
  2. 環境依賴:開發需要完整的後端環境
  3. 測試困難:難以模擬邊界情況
  4. 溝通成本:API 變更需要頻繁協調

Mock API 的解決方案

前端開發 ──Mock API──> 前端完成
後端開發 ──────────────> 後端完成

快速整合測試

前後端可以平行開發。

AppFuse 的 Mock 策略

核心原則

  1. API 規格優先:先定義 API 規格,Mock 和真實 API 都遵循
  2. 行為模擬:不只回傳資料,也模擬業務邏輯
  3. 漸進切換:支援逐步從 Mock 切換到真實 API

架構設計

使用 MSW 的優勢

為什麼選擇 MSW?

方案優點缺點
手動 Mock簡單不真實、難維護
Mock Server接近真實需要額外服務
MSW攔截層、無需伺服器學習曲線

MSW(Mock Service Worker)在瀏覽器層攔截請求,不需要修改應用程式碼。

MSW 的工作原理

1. Service Worker 攔截 HTTP 請求
2. 匹配定義的 Handler
3. 回傳模擬的回應
4. 未匹配的請求通過到真實 API

Mock 設計模式

1. In-Memory Database

模擬資料庫的 CRUD 操作:

// 記憶體資料庫
const db = {
products: [...initialProducts],
orders: [...initialOrders],
};

// CRUD 操作
db.products.push(newProduct);
db.products = db.products.filter(p => p.id !== id);

優點:狀態持久(頁面重整前)、支援關聯查詢

2. 多租戶隔離

模擬 SaaS 的租戶隔離:

function tenantQuery(collection, tenantId) {
return collection.filter(item => item.tenantId === tenantId);
}

// Handler 中使用
const products = tenantQuery(db.products, currentUser.tenantId);

3. 延遲模擬

模擬網路延遲,測試 loading 狀態:

http.get('/api/products', async () => {
await delay(500); // 模擬網路延遲
return HttpResponse.json(products);
});

4. 錯誤模擬

測試錯誤處理:

http.get('/api/products/:id', ({ params }) => {
const product = db.products.find(p => p.id === params.id);

if (!product) {
return HttpResponse.json(
{ error: 'Product not found' },
{ status: 404 }
);
}

return HttpResponse.json(product);
});

開發工作流程

階段 1:Prototype

API 規格 → Mock Handler → 前端開發 → Prototype Demo
  • 快速驗證 UI/UX
  • 無需後端環境
  • 可獨立部署展示

階段 2:整合開發

Mock API ──────────────> 前端開發
真實 API ──────────────> 後端開發

漸進切換測試
  • 逐一切換 API
  • 驗證整合正確性
  • 處理資料格式差異

階段 3:生產部署

前端 ──────> 真實 API
完全移除 Mock

權衡取捨

獲得什麼

  • ✅ 前後端可平行開發
  • ✅ 開發環境獨立
  • ✅ 易於測試邊界情況
  • ✅ 可快速建立 Prototype

放棄什麼

  • ❌ 需要維護 Mock Handler
  • ❌ Mock 可能與真實 API 不同步
  • ❌ 某些後端行為難以完全模擬

緩解措施

  1. API 規格驅動:Mock 和真實 API 都從同一規格產生
  2. 自動化測試:驗證 Mock 和真實 API 的一致性
  3. 漸進切換:逐步驗證而非一次全部切換

下一步