graphql logo

背景

絕大多數的實際應用,後端提供的接口基於RESTful風格,而RESTful架構的服務是圍繞資源展開的。隨著業務複雜度的提高,前端畫面訊息和交互體驗愈加複雜。

RESTfull通常會遇到的痛點

1.性能瓶頸

  • 後端往往是採取微服務架構,拆成多個服務,一個頁面往往需要發送多個請求,才能獲取足夠的資料。而對於同一個接口,如果參數有多種組合,需要調用多次才行。
  • 請求的數量越多,以下耗時越多:
    • 隊列等待時間
    • 連接建立和銷毀耗時
    • 後端重複的權限或參數校驗
    • 客戶端與服務器之間來回響應時間

2.數據冗餘

  • 後端提供的接口,通常會在多個頁面中使用,後端無法事先預知前端需要哪些資料,因此幾乎都是返回全部資料,寧多勿缺。隨著業務功能的發展,會加入更多的資料,而且為了保持兼容性,只增不減。

3.文檔缺失

  • 文檔跟接口分離,無法值觀通過接口或者單個聞檔或取所有需要的接口訊息。與此同時,文檔很難與實作完全保持一致,都需要依靠人工來確保資訊正確。

簡介

作為Facebook在2015年推出的查詢與顏,GraphQL能對API的資料提供一套淺顯易懂的完整描述,能使前端更加準確獲取需要的資料。

以下是官方對GraphQL的定義

GraphQl既是一種用於API的查詢語言也是一個滿足數據查詢運行時。
GraphQL對API中的數據提供了一套易於理解的完整描述,使得客戶端能夠準確的獲得需要的數據,而且沒有任何冗餘,也讓API更容易隨著時間推移而演進,還能用於構建強大的開發者工具。

graphql logo

GraphQL的強大表達能力主要還是來自於它完備的類型系統,與REST不同,它將整個Web服務中的全部資源看成一個有連結的圖,而不是一個個資源孤島,在訪問任何資源時都可以通過資源之間的連接訪問其他的資源。

舉個例子,假如有以下的結構 graphql logo

當訪問User資源時,可以通過GraphQL中的連接訪問當前User的Repo和Issue等資源,我們不再需要透過多個REST的接口個別獲取這些資料,只需要通過如下所示的查詢就能一次性拿到全部的結果:

{
    user{
        id
        email
        username
        repos(first:10){
            id
            url
            name
            issues(first:20){
                id
                author
                title
            }
        }
    }
}

GraphQL這種方式能將原有的RESTful多次請求聚合成一次請求,不僅能夠減少多次請求帶來的延遲,還能夠降低server壓力,使得前端渲染速度加快。

GraphQL vs RESTful

與RESTful明顯不同之處,是每個GraphQL服務器對外只提供一個用於調用內部接口的端點,所有的請求都訪問這暴露出來的唯一短點。 graphql endpoint GraphQL實際上將多個HTTP請求聚合成一個請求,只是將多個RESTful請求的資源變成一個從跟資源Post訪問其他資源的Comment和Author的圖,從原有的分散式請求變成了集中式的請求,這種方式非常適合單體服務直接對外提供GraphQL服務,能夠在數據源和展示層建立一個非常清晰的分離,同時也能夠通過一些強大的工具,例如GraphQL直接提供可視化的文檔。

優點

1.精準資料取得

  • 宣告式(Declarative)資料索取
  • 資料只拿剛好且彈性十足
  • 透過資料之間的關係連接(就像一幅Graph),大幅減少來回request的次數

2.程式即文檔

  • 前後端溝通成本減少
  • 實現以資料需求驅動(driven by data requirement)的設計
  • 建立文檔(documentation)的時間成本幾近為0

3.前端控制權提升

  • 過往為了因應不同的平台或是裝置而需要一套新的API系統
  • GraphQL API 則只需要一套,其他交給前端自行決定資料索取的格式&方式
  • 由於GraphQL query與回傳的資料格式幾乎相同,大大減少前端錯估資料樣貌的可能性
  • 前端不再被日益複雜的架構設計綁住

4.高度自由的實作方式

  • 不預設綁任何程式語言或是資料庫
  • 可將不同microservice的GraphQL schema串接在一起

5.強型別

  • 型別錯就直接被擋住
  • 支援五種基礎型別(Scalar Types)

缺點

1.過於自由、規範少

  • 沒有一定的實作規範,可能音錢後端對於架構的疏忽或不了解導致設計出過於複雜的schema
  • 沒有一個成熟的Best Practice時,容易出現Anti Pattern
  • 不懂GraphQL優勢,而設計出一套「RESTfrl GraphQL」

2.學習成本

  • GraphQL不是一項很難的技術,但若要應用到整個公司或架構上的話,仍需要時間推廣及謹慎的設計與討論
  • 很容易一不小心陷入RESTful API的設計思維、埋下更多技術債
  • 很多技術如效能處理、錯誤處理不吐4xx、安全性等等都需要額外的學習

3.Server Side Caching實作困難

  • RESTful API的endpoint固定且資料需求單純,然而GraphQL難以保證每次request的模樣,因此較難實作Caching

GraphQL系列文章走向

因為本身是.Net為主,未來GraphQL系列會用.Net來實作,分享一些經驗、踩雷、資安風險等內容。 目前還沒有算真正在實務上使用,只能自己上網找一些教材下來練習看看,說不定哪天工作上真的會需要用到。

參考資料

https://justinyangis.me/2019/01/26/graphql/
https://ithelp.ithome.com.tw/articles/10200678