WORK STORY / 02
讓 GraphQL 與 REST 共用同一套資料模型與 UI
情境
當時我手上有兩個原本互不相關的前端專案。
一個是以 GraphQL 為主要資料來源的 Application;另一個則是使用 REST API 的 BPM 簽核系統。
BPM 原本處理的資料相對單純,直到一個新需求出現:
BPM 必須匯入 GraphQL 系統中完整而複雜的資料,並且使用相同的 UI 呈現。
這時問題就不只是 Component 能不能搬過去。
GraphQL 專案的 Data Type 來自 Codegen,如果兩邊各自維護型別,同一份資料模型就會出現兩個版本;但如果只是為了一小部分資料,強迫 REST 專案也導入整套 GraphQL Codegen,又讓技術邊界變得很奇怪。
我的判斷與做法
我不希望「資料從 GraphQL 還是 REST 進來」決定 UI 與 Domain Model 要怎麼設計。
所以我把 GraphQL 專案調整成 Nx monorepo,重新拆開:
- Application 自己才需要知道的 GraphQL operation / resolver
- 可以跨專案共享的 Data Type
- 依賴這些資料模型的 UI Component
- parser、formatter 等資料處理邏輯
GraphQL Codegen 產生的核心 Data Type 統一放進 libs/core,與資料模型綁定的 UI 和資料處理能力也由同一個 Library 管理。
REST 專案只需要使用這個共享 Library,不需要因為使用這些資料就理解整套 GraphQL infrastructure。
形成的結果
GraphQL 與 REST 兩個 Application 最後可以使用同一份 Data Model 與同一套 UI。
資料型別不需要人工維護兩份,與資料相關的 Component、parser、formatter 也可以一起演進。
GraphQL 仍然只存在於需要 GraphQL 的 Application 裡,但它所描述的 Domain Model 可以成為跨專案共同使用的來源。
留下的思考
這件事後來成為我很典型的一個架構判斷:
傳輸方式可以不同,但同一個 Domain 不應該因此擁有兩份事實。
GraphQL、REST 是資料怎麼進來的問題。
真正應該成為 Single Source of Truth 的,是系統對這份資料本身的定義。