本章對應原書 2nd Edition 第 14 章。雖然原書放在 Part III「People」,但因為跨多個前端組合 + 後端聚合等技術話題密度高,本 Hugo Book 把它放在「人與文化」部第一章作為人/技術交界的引子。

UI 是把所有微服務「織成有意義的東西呈現給使用者」的地方。本章從組織擁有權技術組合模式兩個角度切入。

走向「Digital」#

過去公司會把 web、mobile 視為兩件事;現在則整體看待——使用者透過任何裝置與我們互動。微服務的細粒度 API 讓我們能依不同情境組合出不同體驗(桌機、行動、穿戴、實體門市)。

所有權模型(Ownership Models)#

反例:層級切的前端團隊#

Figure 14.1:傳統三層團隊——加一個 UI 控制要動三個團隊

問題:每次小修改要協調三個團隊,速度大幅變慢。

推薦:端到端(Stream-Aligned)團隊#

Figure 14.2:每個團隊負責一條業務流的 UI + 後端微服務

來自 Matthew Skelton & Manuel Pais《Team Topologies》:「Stream-Aligned Team」是針對單一有價值的工作流組成的團隊,不需透過交接(handoff)給別人就能交付使用者價值

「Full Stack Team」(不是 full stack developer)才是真正能加速的單位——還能維持與終端使用者的直接連結。

為什麼很多組織還是用前端團隊?#

三個常見理由:

  1. 稀缺專家:UI 設計、互動、無障礙專家不好找
  2. 一致性:UI 視覺與互動要一致
  3. 技術挑戰:SPA(Single-Page Application)框架傳統上難以拆分

解決方案#

共享專家(Sharing Specialists)#

把專家嵌入多個 stream-aligned team,或建立 Enabling Team(賦能團隊)——像內部顧問,幫各 stream team 自我學習,而非代為實作。

類比歷史:以前 DBA 都集中在獨立團隊,現在多數 DBA 工作已下放給開發團隊,DBA 反而能專注真正困難的問題。

確保一致性#

  • 共用設計系統、CSS style guide、UI component 庫
  • 範例:Financial Times 的 Origami team 為各 stream team 提供共用 web component 與品牌一致性
  • 不一致也未必不好:Amazon 的網站與 AWS console 控件風格可說「混亂」,但 Amazon 寧可讓團隊自治、犧牲一致性以換取速度

模式 1:單體前端(Monolithic Frontend)#

Figure 14.3:UI 直接呼叫多個下游微服務

  • UI 全部邏輯與狀態都在前端
  • 後端微服務僅作資料/操作來源(多用 JSON)
  • 適合:單一團隊負責整個 UI + 後端的場景
  • 缺點:多團隊分工時瓶頸明顯;難以為不同裝置裁切

模式 2:微前端(Micro Frontends)#

A style where independently deliverable frontend applications are composed into a greater whole.」

——Cam Jackson 的微前端定義

把前端切成可獨立部署的多塊;對應 stream-aligned team 的所有權邊界。實作分兩種:頁面式分解、widget 式分解。

模式 2a:頁面式分解(Page-Based)#

Figure 14.4:不同微服務各自負責一組網頁

  • /albums/* 由 Albums 微服務負責、/artists/* 由 Artists 微服務負責
  • 共用導覽列把它們串起來
  • 最簡單:不需要花俏的 JS、不需要 iFrame;點連結 → 跳新頁
  • 對純網站(非 SPA)來說,這應該是預設選擇

SPA 風潮讓很多本來適合「網站」的體驗被硬塞進 SPA。網站還是個合理的選擇——別忘了它的簡單與韌性。

模式 2b:Widget 式分解(Widget-Based)#

Figure 14.5:MusicCorp 的購物車與推薦 widget

  • 同一頁面包含多個由不同團隊維護的 widget
  • 每個 widget 可獨立更新、各自呼叫對應的後端微服務

Figure 14.6:推薦 widget 與後端微服務互動

  • 容器(Container)應用負責定義導覽與要載入哪些 widget
  • 真實案例:Spotify 大量使用此模式

實作要點:依賴與通訊#

  • iFrame 有 sizing、跨層通訊問題,多半避免使用
  • 不同 widget 可用不同 framework 版本(甚至不同框架),但會引入大量依賴重複,page weight 暴增
  • 同頁多 widget 間用 custom DOM event 溝通(如 Album Selected 事件)

Figure 14.7:Charts widget 發出事件,其他 widget 訂閱反應

Web Component Standard 理論上是實作 widget 的好工具,但業界推進緩慢——多年下來作者仍未見有組織用它從微服務提供 widget。

page load 大小要持續監控——CNN 首頁載入 7.9 MB,比 Alpine Linux 的 5 MB 還大。設個自動化告警,超出閾值就紅燈。

約束(Constraints)#

不同裝置的限制不同:

  • 桌機 vs 平板 vs 手機 vs 穿戴 vs SMS(南半球高頻使用)
  • 螢幕大小、輸入方式、頻寬、電池
  • 無障礙性:螢幕閱讀器、鍵盤導覽——很多國家有法律要求(如英國 Equality Act 2010)

不同裝置常需要不同呼叫策略——這引出後端聚合模式。

模式 3:中央聚合閘道(Central Aggregating Gateway)#

Figure 14.8:UI 自己打多個微服務並過濾欄位

Figure 14.9:閘道集中聚合下游呼叫並裁切回應

  • 所有 UI 對閘道發單次請求 → 閘道幫忙呼叫多個下游、合併回應、丟掉不要的欄位
  • 也可批次:UI 一次送 10 個 ID,閘道內部展開查詢

多裝置的問題#

Figure 14.10:手機與桌機需求不同,閘道內聚合邏輯爆炸

  • 不同裝置需求差異越來越大 → 閘道內各種裁切邏輯爆炸
  • 閘道變成多團隊共用 → 回到層級式架構的老問題

多重關注點#

API gateway 產品(如 Kong、Apigee)多半擅長 API key、限流、認證等通用議題。別把聚合與裁切邏輯也塞進去

  • 鎖死特定 DSL,移走困難
  • 隔離團隊邊界,造成新瓶頸

想用 API gateway → 用,但只用它做通用基礎設施;聚合 / BFF 邏輯放在自己的程式碼裡。

模式 4:BFF(Backend for Frontend)#

Figure 14.11:每個前端有自己的 BFF

BFF 與中央閘道的核心差異:BFF 是專屬的,由那個前端的團隊擁有。

把 UI 想成兩半:一半在裝置上、另一半(BFF)在伺服器端,兩半同團隊維護

BFF 數量原則#

One experience, one BFF.」——Stewart Gleadow(REA)

同一體驗就用同一個 BFF,不同體驗就分開。組織結構通常是最終決定因素(Conway’s law again)。

Figure 14.12:REA 的 iOS、Android 各擁一個 BFF

Figure 14.13:SoundCloud iOS、Android 共用同一個 BFF

BFF 之間的重用#

「BFF 之間有重複程式碼怎麼辦?」——作者對跨服務重複碼相對寬容,因為強拉抽象常常製造耦合。

三種選擇:

  • 接受重複(多數時候 OK)
  • 抽 shared library——容易產生耦合
  • 新的微服務處理共用邏輯

Figure 14.14:兩個 BFF 都重複呼叫三個下游做相同事

Figure 14.15:抽出 Wishlist 微服務消除 BFF 重複

BFF 的延伸用途#

Figure 14.16:BFF 模式也能用來服務外部 API 消費者

  • 不只給 UI;也可為第三方 API 整合建專屬 BFF
  • 第三方常無法或無意改變介面 → 給每個夥伴一個 BFF,破壞性變更只影響該夥伴

GraphQL:BFF 的另一種實作方式#

{
  order(id: 123) {
    date
    total
    status
    delivery {
      company
      driver
      duedate
    }
  }
}
  • 客戶端動態指定要哪些欄位 → 減少網路 round trip 與多餘資料
  • GraphQL resolver 負責把查詢映射成微服務呼叫
  • 可實作 BFF:依團隊邊界拆出多個 GraphQL server

GraphQL 不是萬靈丹(第 5 章詳述):難快取、寫入操作不如讀取流暢、容易引誘人把微服務當資料庫薄殼。但作為 BFF 實作方式,動態查詢能力很實用。

自包含系統(Self-Contained Systems, SCS)#

SCS 概念主張:每個 SCS 是自治的 web 應用、由一個團隊擁有、不共用 UI、不共用業務碼、優先非同步通訊。

作者認同其精神,但覺得它太規範化(如必須是「web 應用」),也擔心它把焦點放在活動而非結果。實務上,做好 stream-aligned team 與 BFF/微前端就涵蓋了 SCS 想達成的多數目標。

混合策略#

各模式不互斥:

  • 網站用 頁面式分解(每個區段獨立部署)
  • 內含 widget(推薦、購物車)
  • 行動端用 BFF(搭配 GraphQL 動態查詢)

關鍵:核心業務邏輯仍住在領域微服務裡,不要散到中介層。

小結#

  • 不要繼續維持「專屬前端團隊」這種層級切的組織模式(除非你打不破)
  • 微前端讓 stream-aligned team 真的能 end-to-end 擁有功能
  • 頁面式分解 → 一般網站;widget 式 → SPA 框架時的選擇
  • 不同裝置需要不同聚合策略 → BFF(每裝置一個)優於中央閘道
  • GraphQL 可作為 BFF 的查詢實作層
  • 混搭 OK,但核心領域邏輯一定留在微服務裡