閱讀526 返回首頁    go 阿裏雲 go 技術社區[雲棲]


GraphQL提供數據接口新思路之數據聚合解決方案

目標:框架打造,別具匠心。服務於業務的數據聚合平台。

screenshot

引言: 蜂巢內容平台麵臨的挑戰:互聯網的發展,多端的數據展現和業務數據聚合,如何最佳的根據的查詢條件給出不同的數據聚合和數據格式? 所見即所得,是前端人員或者是接入內容平台的業務方最希望看到的結果。一切讓調用者自己定義格式和請求條件。

GraphQL涉及哪些場景

一個GraphQL查詢是一個字符串,它被發送給一個與數據模式無關的服務器,然後服務器返回JSON數據。GraphQL是強類型的,並避免了版本控製,同時提供了隨著數據演進可以輕易改進查詢語句的能力。

現有的業務場景一般是這樣的,業務方提出需求,然後尋找開發資源,由後端提供數據,讓前端實現各種不同的業務視圖。這樣的做法存在很多的重複勞動,如果能夠將其中通用的內容抽取出來提供給各個業務方反複使用,必然能夠節省寶貴的開發時間和開發人力。

前端的解決方案是將視圖組件化,各個業務線既可以是組件的使用者,也可以是組件的生產者。那麼問題來了,前端通過組件實現了跨業務的複用,後端接口如何相應地提高開發效率呢?

我們假設某個業務需要以下數據內容 a:

{
  user(id: 3500401) {
    id,
    name,
    isViewerFriend
  }
}

對,這不是 JSON,但是我們仍然可以看懂它表示的是查詢 id 為 3500401 用戶的 id,name 和 isViewerFriend 信息。用戶信息對於各個業務都是通用的,假設另外一個業務需要這樣的用戶信息 b:

{
  user(id: 3500401) {
    name,
    profilePicture(size: 50)  {
      uri,
      width,
      height
    }
  }
}

對比一下,我們發現隻是少了兩個字段,多了一個字段而已。如果要實現我們的目標,即複用同一個接口來支持這兩種業務的話,會有以下幾種做法:

用同一個接口,這個接口提供了所有數據。這樣做的好處是實現起來簡單,但缺點是對業務做判斷的邏輯會增多,而且對於業務來說,響應內容中有些數據根本用不到;
使用參數來區分不同的業務方並返回相應的數據。好處仍然是實現簡單,雖然不會有用不到的數據返回,但是仍然需要增加業務邏輯判斷,會造成以後維護的困難。
此外,這樣還會造成不同業務之間的強依賴,每次發布都需要各個業務線一起測試和回歸。不重用接口則沒法提高開發效率,重用接口則會有這些問題,那麼到底有沒有“好一點”的解決方案呢?

這是我們在處理複雜的前後端分離中經常要麵臨的一個思考。

1. GraphQL,一種新的思路

我們知道,用戶信息對應的數據模型是固定的,每次請求其實是對這些數據做了過濾和篩選。對應到數據庫操作,就是數據的查詢操作。如果客戶端也能夠像“查詢”一樣發送請求,那不就可以從後端接口這個大的“大數據庫”去過濾篩選業務需要的數據了嗎?

GraphQL 就是基於這樣的思想來設計的。上麵提到的(a)和(b)類型的數據結構就是 GraphQL 的查詢內容。使用上麵的查詢,GraphQL 服務器會分別返回如下響應內容。

a 查詢對應的響應:

{
  "user" : {
    "id": 3500401,
    "name": "gulai",
    "isViewerFriend": true
  }
}

b 查詢對應的響應:

{
  "user" : {
    "name": "gulai",
    "profilePicture": {
      "uri": "http: //someurl.cdn/pic.jpg",
      "width": 50,
      "height": 50
    }
  }
}

隻需要改變查詢內容,前端就能定製服務器返回的響應內容,這就是 GraphQL 的客戶端指定查詢(Client Specified Queries)。假如我們能夠將基礎數據平台做成一個 GraphQL 服務器,不就能為這個平台上的所有業務提供統一可複用的數據接口了嗎? 如果定位為:數據服務標準化管理,數據網關也是不錯的架構。

screenshot

擁抱 DIP平台無縫集成,它要是什麼格式,我們給出什麼格式(前後端都開心^_^)

screenshot

借助於Antlr語法解析:
參考: https://www.antlr.org/
screenshot

2, 查詢條件自由組合 QSQL

1) 如何讓各種條件組合+邏輯判斷一起使用,很自然想到的是SQL函數。
screenshot

2) GraphQL同樣支持條件傳遞和變量替換,讓查詢串和請求格式串分離。

screenshot

3) 最終圍繞多維度數據聚合進行思考
聚焦:
screenshot
層次:
screenshot

3, 整合蜂巢場景化內容平台

1)在服務上聲明
screenshot
2)關鍵詞進行關聯方法調用
screenshot
3)Spring啟動的後進行GraphQL注冊服務
screenshot

4,如何解決N+1問題?

我們先看看graphQL的執行流程 。
回到語法樹的遍曆: 深度遍曆或者廣度遍曆(解決LIST數據批量獲取的特性)
深度遍曆
screenshot
廣度遍曆
screenshot

我們采取廣度遍曆算法,構建相同的節點采取批量直接構建List List這樣的形式請求領域服務,完成批量問題調用。

參考:

規範:https://github.com/chentsulin/awesome-graphql
代碼參考:https://facebook.github.io/graphql/
InfoQ: https://www.infoq.com/cn/news/2015/10/graphql-your-schema?_t=t

總結:

後續還有很多優化和配套工具需要繼續完善,其中包括內容平台的領域模型標準化建設,一鍵建站服務,垃圾防控,性能優化和限流降級和接口監控等。

最後更新:2017-10-17 18:03:25

  上一篇:go  解讀OpenMessaging開源項目,阿裏巴巴發起首個分布式消息領域的國際標準
  下一篇:go 雲棲大會,當我們看“拔電源”時,我們看的其實是……