WORK STORY / 02

讓 GraphQL 與 REST 共用同一套資料模型與 UI

CONTEXT

情境

當時我手上有兩個原本互不相關的前端專案。

一個是以 GraphQL 為主要資料來源的 Application;另一個則是使用 REST API 的 BPM 簽核系統。

BPM 原本處理的資料相對單純,直到一個新需求出現:

BPM 必須匯入 GraphQL 系統中完整而複雜的資料,並且使用相同的 UI 呈現。

這時問題就不只是 Component 能不能搬過去。

GraphQL 專案的 Data Type 來自 Codegen,如果兩邊各自維護型別,同一份資料模型就會出現兩個版本;但如果只是為了一小部分資料,強迫 REST 專案也導入整套 GraphQL Codegen,又讓技術邊界變得很奇怪。

DECISION & ACTION

我的判斷與做法

我不希望「資料從 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。

OUTCOME

形成的結果

GraphQL 與 REST 兩個 Application 最後可以使用同一份 Data Model 與同一套 UI。

資料型別不需要人工維護兩份,與資料相關的 Component、parser、formatter 也可以一起演進。

GraphQL 仍然只存在於需要 GraphQL 的 Application 裡,但它所描述的 Domain Model 可以成為跨專案共同使用的來源。

REFLECTION

留下的思考

這件事後來成為我很典型的一個架構判斷:

傳輸方式可以不同,但同一個 Domain 不應該因此擁有兩份事實。

GraphQL、REST 是資料怎麼進來的問題。

真正應該成為 Single Source of Truth 的,是系統對這份資料本身的定義。