GraphQL

GraphQL v.s REST

首先,看到這個標題,要先了解一下什麼是「REST」; 我們在先前的文章中有提到關於 Firebase Database REST API 的內容, 但並沒有在文章內解釋其含義是什麼。

REST

REST(Representational State Transfer),是一種架構,而非協定或是標準; 透過 HTTP 協議所提供的動作(POST、GET、PUT、DELETE)來對資源進行 CRUD(Create、Read、Update、Delete), 並以 URI 的方式來指定資源:

  • POST /games:建立遊戲
  • GET /games:取得遊戲清單
  • PUT /games/123:修改 id = 123 的遊戲內容
  • DELETE /games/123:刪除 id = 123 的遊戲 在 iOS 開發的串接 RESTful API 的經驗中,不論是取得的資料,或是回傳回 server 的資料, 大多是以 JSON 的格式在做溝通。 前後端之間可以透過 RESTful 的方式進行明確的溝通,進而開發出相對應的功能。

REST 的缺點

但有時候還是會遇到一些問題

會拿到多餘的欄位

巢狀資源的處理 越來越多支 API 會拿到多餘的欄位

有時候我們為了顯示一個商品,在畫面上需要呈現

  • 商品名稱
  • 價錢
  • 照片 URL

但可能在 GET /products/1 的時候,會拿到整個商品的資料回來:

  • 商品 ID
  • 名稱
  • 價錢
  • 剩餘數量
  • 照片 URL
  • 建立時間
  • 最後更新時間 不過在顯示端僅需要呈現三個項目,那麼其他回傳的資料就浪費了彼此之間的網路傳輸。

巢狀資源的處理

像是在一個畫面中,需要顯示「我的最愛」; 在 REST 的架構下,我們會設計出兩支 API:

GET /users/1/favorites:取得 id = 1 的會員的最愛清單 GET /books/123:取得 id = 123 的書本資料 我們會在第一支 API 中取得一個書本 ID 列表,再來呼叫第二支 API 來取得書本資訊; 如果將書本的資訊直接併入最愛之中,雖然可以減少查詢的次數,但又會在某些不需要關聯的時候, 而讓書本成為多餘的欄位。

於是乎就會越來越多支 API

上述幾種狀況,可能就會開始出現:

  • GET /products-with-photo
  • GET /products-with-price
  • GET /products-with-users 之類的,為了配合某些前端的顯示需求而特化的 API,為了一次取得多個物件回傳, 但這也破壞了 REST 原先的架構設計風格。 所以,Facebook 便在 2012 年開始在公司內部使用另一種架設風格來解決這些問題:

GraphQL

GraphQL 是由 Facebook 所提出的一種 query language,從 2012 年內部開始使用,到 2015 年 7 月開源。 其精神便是將所有的 API 都統整成一支 GraphQL 的 API:

  • GET /graphql?query={ user(id: “1”) { name, address { zipCode } } }
{
    "name": "Archie",
    "address": {
        "zipCode": "12345"
    }
}

回傳的資料由呼叫 API 的人決定,有點像是讓呼叫人的負責下 query 的條件。 讓前後端共同使用一份 schema 來定義出個物件的 type 和定義好 Query 這個物件的內容, 再來就由呼叫方來自由發揮需要取得哪些資訊自訂組裝。 比較強烈的比較在於:

  • 只有一支 API(也就是只有一個 endpoint)
  • 可以自行處理巢狀資料
  • 可以自行決定拿到哪些欄位 進而改善上面所提到的問題。

結論

對於 iOS 的開發人員而言,是一種蠻新潮且有趣的串接方式, 但在後端就不知道是一個怎樣的複雜程度了⋯⋯畢竟我比較著重在 iOS 的應用方面, 有興趣的人可以看看我所一開始看的這篇文章。

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus