GraphQL + Space Cloud 簡化你的API設計
- 2020 年 3 月 6 日
- 筆記
服務端API的設計與開發,為客戶端提供產品業務所需要的各種功能和數據接口。隨着APP產品的迭代更新,APP Server提供的接口往往也會進行多個版本的迭代更新。如何優雅的維護接口的穩定性,設計擴展性滿足將來一定的業務需求變更,一直是從事服務端接口開發工程師需要不斷思考的問題。
特別的,當你同一個服務的接口需要服務於多個需求不盡相同的客戶端時,你的接口設計工作會變得尤其重要:
- 你可能會開始為接口提供各種option,以支持不同的客戶端接入使用不同的option滿足不同的需求;
- 你可能會將數據接口粒度拆分得更小,以支持不同客戶端組合不同的API得到自己需要的數據;
- 你可能還需要提供通用的batch批量請求接口,以解決客戶端通過蜂窩網絡遠程調用多個數據接口延時增大的問題,又或者為某個客戶端接入量身定製滿足需要的接口;
之所以會產生這樣的接口維護成本,一個原因在於這裡API接口的設計承擔了數據表示的職責:為前端的UI/UX提供展現所需要的數據。比如APP上的個人中心頁面,UI/UX需要展現昵稱,頭像,性別的數據,這是一個來自UI/UX對數據接口返回的需求。
有沒有可能將來自UI/UX的需求盡量控制在UI/UX的實現端(客戶端)從而減少UI展示層的邏輯變化的複雜度對後端接口的影響呢?
GraphQL 專註於數據建模
2012年Facebook移動端從H5改用IOS原生應用重新開發時遇到了類似的問題,新的APP產品設計使得原來的很多REST API不再適用或者使用過濾繁瑣。解決這一問題,Facebook在接入層添加了一層稱為GraphQL的查詢語言。並於2015年,發佈了GraphQL的規範及其javascript版本的參考實現。
如果說傳統的REST接口類似一個售貨機,每次按一個按鈕獲得一個對應的貨物,需要5個不同貨物你需要按5下,那麼GraphQL彷彿一個智能按鈕,可以讓你通過表達你的需求一次獲得需要的所有貨物。GraphQL讓服務的設計者可以專註於數據建模,而非接口的數據表示和組織。服務的設計者完成數據建模定義好服務的數據能力,服務使用者可以通過GraphQL表達自己的需求來按需得到自己需要的數據,不多也不少。其中GraphQL中的Graph意指數據模型中數據之間的關聯關係類似於連接不同節點的邊構成一個圖。

具體的,GraphQL有3個主要組成部分:
- Queries:客戶端的請求即一個查詢;
- Resolvers:服務端通過resolver的方式告訴GraphQL每個查詢字段的數據如何獲取;這也使得API數據模型和後端的數據庫表結構/外部存儲得以解耦;
- Schema:描述服務端的能力的數據模型,客戶端基於這個數據模型進行查詢操作。
GraphQL通過一個統一的HTTP API接口來傳遞數據:通過文本描述數據請求需求,接口返回匹配需求的數據。如下圖,行1~8為客戶端請求的GraphQL形式的需求描述,該請求查詢id為1的作者的名字,以及要求返回其關聯的id為5的一本書的標題;行10~21為對應的匹配客戶端數據需求的返回。在這裡我們可以看到,客戶端有了表達自身數據需求的靈活性。類似的GraphQL中也定義了對數據進行修改的語法。

從2016年開始,隨着GraphQL在不同編程語言上的生態的豐富,這項技術開始被Twitter,Yelp,Airbnb等公司應用於自己的產品中,如下圖目前GraphQL已經在近100家不同規模的企業中開始使用。

Space Cloud 加速API開發
如果說GraphQL做的事情是把服務端提供的接口職責與使用者劃分清楚,那麼Space Cloud想做的事情是在這個職責範圍內如何讓開發工作可以更快的完成。
如下圖,Space Cloud是一個新的API接入層解決方案,它可以對接後端不同類型的數據庫,微服務以及文件存儲,為前端提供統一的GraphQL接口。Space Cloud使得對數據庫進行CRUD(增刪改查)操作的接口可以被快速實現,提供對接微服務接口的能力使得系統原有REST風格的接口可以被組裝並以GraphQL接口的形式統一對外提供。

具體的,Space Cloud服務部署後,提供了一個管理界面(Misson Control)。如下圖,在管理界面上新建項目後,你可以在界面上新建數據庫連接(提供數據庫實例的連接信息),並通過運行GraphQL的方式新建數據表。


如上圖的GraphQL往數據庫中創建了trainer & pokemon兩張表,在ID上建立了外鍵關聯。與此同時,在未寫任何代碼的條件下通過GraphQL接口對外提供了這兩個數據模型的增刪查改接口能力。你可以開始使用GraphQL接口進行查詢數據/插入數據等,Space Cloud為你實現了背後的數據resolver邏輯。比如下面是一個連表查詢的操作及其返回的結果(注意,這裡你並不需要寫連表查詢的SQL語句)。

通常來說,我們有很多接口邏輯不是簡單的數據庫增刪改查可以完成,這種情況Space Cloud提供了微服務接口接入的功能。類似的,你可以在Space Cloud的管理界面上聲明你的REST API的接口信息(請求路徑,參數,響應格式等)。比如你有兩個微服務的HTTP接口:
- /add接口:接收兩個參數,返回兩個數的和;
- /double接口:接收一個參數,返回其乘以2的值;
在完成接口的聲明後,你就自動的獲得了通過GraphQL訪問接口能力,同樣的不需要任何編程。而藉助與GraphQL的並行和嵌套語法,你自動的獲得了將微服務與數據庫操作進行組合或者並行查詢的能力。比如以下的查詢,客戶端可以在一次請求中,並行地完成某個數據的查詢操作以及對兩個微服務接口的調用;

再比如以下的查詢,客戶端可以在一次請求中,完成對某個數據的查詢操作並對其返回結果中的某個字段調用另一個微服務接口(/double)進行加工處理。

而這些功能的實現,還未進行太多的編碼工作,是不是很酷?
Space Cloud基於Apache 2.0協議開源,使用golang語言開發,從2018年下半年開始至今總體上目前還是一個比較年輕的項目。它在加速應用進入市場方面有一些不錯的思路,新的應用開發不妨可以試試這項技術。