高效開發:你的項目有接口聚合服務嗎?

本文首發於我的微信公衆號:coder小黑前端

服務拆分的痛

服務拆分以後,先後端同窗之間關於 API 粒度的爭吵愈來愈常見:小程序

「前端同窗請求兩個接口,聚合一下數據不就好了?」後端同窗想只提供業務領域基礎 API 服務能力,數據組裝處理則但願由前端同窗完成。後端

「後端聚合一下,前端能夠少一次請求,只負責頁面渲染!」前端同窗但願只負責頁面渲染,而 H五、APP、小程序同一個聚合邏輯可能會出如今三端,後端聚合則只須要一次。api

接口聚合服務就是咱們的一個解決思路。緩存

接口聚合服務是什麼?微信

接口聚合服務就是一個搬運工,只是幫助前端同窗聚合多個接口的返回數據,聚合以後一次性返回相應請求的結果給客戶端。咱們但願經過接口聚合服務這個中間層,作到可讓前端直接獲取數據,然後端也能繼續專心於提供基礎業務領域 API 服務能力。數據結構

場景分析

  • 場景一:串行獲取數據。多個請求,有關聯關係。
    • 例如:經過商品 ID 獲取評論信息,經過評論中的 uid 獲取用戶信息
  • 場景二:並行獲取數據。多個請求,無關聯關係。
    • 例如:經過商品 ID 獲取商品信息、獲取商品活動信息、獲取當前用戶已購信息

方案調研

方案 A 方案 B
調用者 客戶端 客戶端
API-Server 自研 GraphQL
Payload 約定 GraphQL
Response 約定 GraphQL
容錯 約定 約定
動態選取字段

最終咱們選擇了方案 A,經過自研一套簡單的接口聚合中間層來解決這個問題。框架

因而,就有了接口聚合服務:api-aggregator。該框架有以下幾個特色:性能

  • 核心代碼在千行左右,輕量級實現ui

  • 對現有代碼無侵入性,無需對現有服務和代碼作改造適配,現有接口可直接使用。

  • 提供了 ApiAggregatePostProcessor 拓展點來干預接口聚合的各個階段,可拓展性強

  • 對前端友好,前端同窗能夠自定義返回數據結構,支持字段動態選取。

  • 接口聚合邏輯直接經過配置文件和 api-aggregator 交流,新增聚合接口,無需發佈

api-aggregator:接口聚合服務

api-aggregator

api-aggregator 認爲一個聚合接口應該是由若干個接口的返回結果聚合而成的,所以在設計時,咱們將其被劃分爲兩個部分:接口元信息和接口之間的聚合邏輯。

ApiDefinition:接口元信息

ApiDefinition 不只定義了接口的元信息,同時也描述了接口所需參數的來源。

api-aggregator 認爲在一次接口聚合中,元信息接口的參數可能有如下一些來源:

  1. 直接由客戶端傳遞過來,即直接從 HttpRequest 中獲取參數。
  2. 從上個接口的返回值中獲取。例如:經過商品 ID 獲取評論信息,經過評論中的 uid 獲取用戶信息。此時 uid 參數就須要從上個接口的返回值中獲取。

ResponseDefinition:接口間聚合邏輯

ResponseDefinition 描述了接口間的聚合邏輯,經過 ResponseDefinition 前端同窗能夠自定義接口返回的數據結構,也能夠動態選取所需字段。

描述接口聚合關係

若是沒有 ResponseDefinition,則 api-aggregator 只能簡單的將兩個接口的數據平級的聚合在一塊兒(如上左圖所示)。而如今,能夠經過 ResponseDefinition 來定義返回結構體,給前端同窗更好的開發體驗(如上右圖所示)。

簡單聊聊設計

配置文件預加載

接口聚合配置信息是由前端開發同窗在管理後臺配置的。

前端同窗在提交配置文件以後,api-aggregator 就會對配置文件作一些靜態分析:分析接口的依賴狀況,是否存在循環依賴等問題。

爲了提升性能,api-aggregator 將相關的配置信息解析好以後,會直接緩存在內存中,以減小對同一份配置文件的反覆解析,同時,再經過定時刷新和 MQ 的 pub/sub 來保證數據的一致性。

簡化 http 請求模型

HttpMethodInvoker

api-aggregator 抽象了 HttpMethodInvoker 來發起 HTTP 請求。經過 Supplier 來獲取返回結果,屏蔽了不一樣 Http Client 之間的 API 差別。

還記得前文提到的場景嗎?

場景一:串行獲取數據。多個請求,有關聯關係。

場景二:並行獲取數據。多個請求,無關聯關係。

在 api-aggregator 中,將這兩個場景進行了簡化合一。

首先, api-aggregator 在解析配置文件分析接口依賴時,會根據接口的依賴狀況給出一個 api-aggregator 認爲是最優的 HTTP 請求流程,而不是根據配置文件定義的接口順序依次請求。

舉個例子:

假設在一次接口聚合中,須要請求接口 A、B、C,而接口 B 的數據依賴於接口 A,接口 A 和接口 C 的請求參數都可直接從 HttpRequest 中獲取參數。

那麼,在實際的接口聚合過程當中,api-aggregator 會先請求接口 A 和接口 C,而後阻塞獲取接口 A 的返回結果,最後請求接口 B。

提供擴展點

api-aggregator 提供了 ApiAggregatePostProcessor 來方便後續擴展。

經過 ApiAggregatePostProcessor,api-aggregator 能夠干預一個接口聚合的整個流程,例如:緩存接口信息、增長監控日誌等等。

ApiAggregatePostProcessor

雖然經過 ApiAggregatePostProcessor 能夠來干預接口的聚合流程,可是想要添加新的 Processor 時仍是須要重啓api-aggregator。而 api-aggregator 做爲接口聚合點,和網關類似,也是流量的集中點,在後續的版本中,可能會考慮引入 Groovy 腳本,來支持動態的開啓和停用 Processor。

最後,歡迎你們在評論區一塊兒留言討論,感謝你的閱讀~~


歡迎關注我的公衆號:

Coder小黑
相關文章
相關標籤/搜索