❯❯ mock server+typed client:前端不等後端的全速開發
📍 流水線位置|入口 → flow → 型別 → 【mock】 → 測試 → UI → vibe → 上線
前端最常卡住的不是 code 寫不出來,是等:等後端把端點交出來、等環境可以聯調、等出問題再拉群一起排查。一般的解法是先在畫面上塞假資料把版刻出來,等後端好了再回頭接。
婚禮系統開工那陣子,業務規格早就透過 Spec 定案,但真正的資料庫連一張表都還沒建。照這個劇本,我應該要開始等了。
但我一天都沒等,也沒塞假資料。上一站立好型別合約後,我順手把 Mock Server 架了起來,讓前端從第一天就全速開發。
常見的做法是把測試資料寫死在前端元件(Hardcoded Data)裡,畫面先動起來再說。我沒這樣做,原因很簡單:流水線後面的自動化測試全都必須對著真正的 HTTP 端點發請求,假資料埋在 client 裡,測試根本餵不到。所以 mock 一開始就開在真正的 Server 端點層。
這些 Mock 路由直接放在 server/api/ 下,跟未來的正式 API 端點共用同一套路徑結構。兩者唯一的差異,只在 Mock 端點把狀態暫存在 server/mock/data/ 的記憶體陣列裡(重啟就重置),不對實體資料庫做持久化寫入。
對前端來說,呼叫 Mock 端點跟呼叫正式 API 在通訊協定層沒有任何差別:同樣發標準 HTTP 請求、收回應,全程被型別合約管著。寫元件的時候,我完全不需要關心後端資料庫蓋到了哪裡。
當然,Mock 資料本身也得遵守型別合約與業務不變量。
拿接待帳號模組當例子:
// server/mock/data/accounts.ts
export interface MockReceptionAccount {
// ...
passwordHash: string // 空字串=未設密碼、不可登入(僅作名單管理)
}
export const mockReceptionAccounts: MockReceptionAccount[] = [
{ accountId: 'account-001', weddingId: 'wedding-001',
username: 'reception-desk-1', passwordHash: '' },
]
像 passwordHash 空字串這種邊界值,我直接把業務意涵寫進欄位註解,免得日後出現「型別過了、業務邏輯卻對不上」的假資料。

到前端這端,所有 API 請求會統一收進 app/api/ 進行封裝。
這是接待帳號模組的 API 客戶端實作片段:
export function listReceptionAccounts(
weddingId: MaybeRefOrGetter<string>,
options?: HttpGetOptions<ReceptionAccountListItem[]>,
) {
return useHttp().get<ReceptionAccountListItem[]>(
() => `/api/v1/weddings/${toValue(weddingId)}/reception-accounts`,
options,
)
}
UI 元件只能透過 listReceptionAccounts(weddingId) 這類介面發請求,不准在元件裡自己拼 URL、也不准直接呼叫原生的 Fetch API。這樣封裝有三個好處:
集中化路由管理:
當端點路徑更換時,只需修改單一客戶端函式即可全域生效。
型別安全驗證:
當 API 回應型別發生變動,TypeScript 編譯器能在第一時間自動攔截錯誤。
統一交織點(AOP):
不論是帶 Auth Header、處理 401 登入過期,還是全域 Error Handling,都在這層一次搞定。

此外,在發送策略上也做了分工:資料讀取統一走 useFetch Hook(支援 SSR 狀態預載),寫入則用 $fetch(操作時機明確),避免伺服器端與客戶端渲染行為不一致。
把 Mock Server 與 Typed Client 組合起來,前端進度就跟後端實體資料庫徹底解耦了。在實體資料庫建起來之前,我已經做完 27 個前端頁面,跑過超過 160 條 E2E 測試。
因為前後端都緊扣同一份合約,這批在 Mock 階段寫出來的 UI 程式碼與測試邏輯,未來切換至正式後端時可以維持運作。
把 Mock Server 排在前面,還有一個核心考量:替測試驅動開發(TDD)鋪路。自動化 E2E 測試要對著具體的 HTTP 端點發請求才能斷言;後端端點還沒交付前,Mock Server 就是測試運作的目標端點,「先寫測試、後實作 UI」的循環才轉得起來。
系統由 Mock 遷移至實體後端的具體實作,核心只需要切換全域設定檔中的環境變數 URL。完整的對接細節與實戰演練,Day 23 會拆給你看。
至於這套「假後端」驗證到底夠不夠真實?真的接上實體後端會不會當場露餡?明天就來回答。
🎒 最小一步|把後端還沒交付的 API 回應先寫成標準 JSON,用任何簡易 server 開出端點,你的前端今天就能對著真的 HTTP 請求開發。
📎 本篇證據|app/api/accounts.api.ts(client 端封裝原始片段)・server/mock/data/(Mock 資料結構定義)