iT邦幫忙

2022 iThome 鐵人賽

DAY 16
0
Modern Web

前端技能樹的十萬個為什麼系列 第 16

Day 16 - 為什麼要用 GraphQL

  • 分享至 

  • xImage
  •  

前言

昨天討論完 RESTful API,今天來看看截然不同的 GraphQL!

先想一下

  • GraphQL 是在什麼樣的時代誕生的?
  • GraphQL 怎麼解決問題?
  • GraphQL 的優缺點是什麼?
  • GraphQL 適合什麼情境?

GraphQL 是在什麼樣的時代誕生的?

GraphQL 到 2015 年才對外發布,但在這之前,REST 的概念從 2000 年就已經提出,大家也用了十多年了,幾個顯著的問題,昨天也討論過了。

如果一個頁面要呈現多種 schema 的資料,比如一個 blog 系統,我手上有 user 的 id,需要呈現這樣的畫面:

如果是用 RESTful API,可能會需要打三次 API:

/user/<id>
/user/<id>/posts
/user/<id>/followers

而且以第一支 API user 來說,即便我只需要 user 的名字拿來顯示,後端仍有可能幫我將生日、星座、血型、祖宗十八代(?)都撈出來,但至少我在這個頁面是不需要多餘的資訊的,除了浪費頻寬,資料多傳就增加了 bug 出現的機率

GraphQL 怎麼解決問題?

GraphQL 是一個針對 API 的查詢語言

A query language for your API

最大的賣點在於,GraphQL 採用 declarative data fetching:

比較 Imperative 與 Declarative data fetching

Imperative data fetching

  1. 建立並送出 HTTP request(比如透過 fetch)
  2. 收到 response 後經過 parse
  3. 將資料儲存在 local memory
  4. 使用資料(比如顯示在 UI 上)

Declarative data fetching

  1. 描述需要的資料結構
  2. 使用資料

這部分是參考 How To GraphQL,其實也沒有什麼神奇的魔法,步驟之所以會變得簡單,單純就是因為 GraphQL 將其他雜事處理掉了。

描述需要的資料結構

回到上面 user blog 的問題,如果是使用 GraphQL 來處理,可能會描述這樣子的資料結構:

query {
    User(id: "er3tg439frjw") {
        name
        posts {
            title
        }
        followers(last: 3) {
            name
        }
    }
}

精準取得資料

由於是前端自行宣告,需要取得哪些資料,所以後端回傳的資料是「精準」的,不多也不少,避免了這兩種狀況:

  • Overfetching:撈太多資料到前端,但其實用不到
  • Underfetching:一次 API request 無法取得所需的所有種類資料(n+1-requests problem)

GraphQL 的原理

如果觀察過 GraphQL 前端發送出去的 request,會在 payload 發現,雖然是送出長得很像 JSON 的結構,但實際上它是個 string

GraphQL 會將查詢的語法透過解析器轉換成語法樹,再遞迴呼叫每個欄位對應的 resolver,透過它去處理每個欄位該產生什麼值,最後匯集起來一次回傳。

GraphQL 的類型

簡單區分了三種類型,且大多時候只會用到 query 與 mutation,相對來說好懂很多:

  • Query:查詢資料(CRUD 中的 R)
  • Mutation:異動資料(CRUD 中的 CUD)
  • Subscribe:透過 Websocket 技術,當資料有異動時,會發布通知給前端

GraphQL 的優缺點是什麼?

優點

  • 強型別:可以自動產生文件,避免型別錯誤,搭配 TypeScript 特別快樂!
  • 單一請求:多個請求可以合併成一個 request
  • 精準資料:由前端決定需要取得哪些欄位,精準取得自己需要的資料,同時節省流量

缺點

  • 缺乏狀態碼:除非特定的錯誤,否則一律回覆 200,有錯誤的話只能塞在 response 裡面
  • Endpoint 都長一樣:所有前端的 request 都是 POST 同一個網址,在 developer tool 需要點進 payload 才有辦法辨別

GraphQL 適合什麼情境?

針對現在前端裝置愈來愈多元,最基本就會有 web 與 app 端,在後端同一個情況下,不同平台所需的資料數量、格式都不同,能負擔的資料傳遞速度也不同(app 顯然不能傳太大量的資料)。

因此在這種情況下,GraphQL 做為一個 API 的查詢語言是非常方便的,因為不管你的 client 用什麼寫,反正只要傳送的 request 符合 GraphQL 的格式,就都通用!而且還可以只選擇自己真正需要的資料。

同時,如果系統的 schema 設計很複雜,比如像是 Facebook,同一個頁面同時要呈現發文者、文章、like、留言、留言的 like 等,這樣的資料型態也很適合 GraphQL,可以一次 request 就取得不同種類的資料

結語

心智圖放大版

GraphQL 也是我今年才開始使用的工具,其實剛開始用起來很卡,因為腦中已經是根深蒂固的 RESTful API 觀念,一次一個 API 一個資源,要轉移到 GraphQL 這種「圖像連結」的思維,反而費了我不少功夫。

的確工具是看狀況用的,即便 GraphQL 是比較新的產物,但也不是說任何環境都無腦使用就是最佳解,有時候還需要考量「適性」的問題,找到適合這個時間點的工具,才是重要的!

參考資料

GraphQL
深入前端現代開發 - GraphQL


上一篇
Day 15 - 為什麼要用 RESTful API
下一篇
Day 17 - 為什麼要用 TypeScript
系列文
前端技能樹的十萬個為什麼30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言