iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 1
16

GraphQL 封面圖

Hi 大家好,我是 Fong,會接觸 GraphQL 是因為目前的公司使用它來做後端的 API,因此想來紀錄一下這段學習的歷程及總結,這一系列文章除了講解技術以外也會介紹 GraphQL 的設計精神,我也會同時提供一些經驗談談談一些使用上的想法及踩雷心得 XD


簡介一下,
GraphQL 是一種為 API 設計的資料查詢(修改)的語言
使得 client 端可以使用更直覺且彈性的語法來取得或修改資料。

這項技術是由 Facebook 從 2012 年開始使用,
為了因應跨裝置及開發 News Feed 功能而開發,
後來覺得用得太爽了,
所以就於 2015 公開釋出 ,讓大家一起爽 (原文)

大概念上有點類似 SQL,
使用者透過輸入定義好的語法,
取得所需的資料 (如 SELECT) 或是修改指定的資料 (如 CREATEUPDATE)。

不過 GraphQL 主要使用於應用服務之間的溝通(尤其是前後端)。
可以想像是一種新型態的 RESTful API,
但是有更多更強大的功能!

至於為什麼他這幾年聲勢看漲,
許多知名企業如 Github 、 Shopify 、 Coursera 、 Twitter 都開始使用呢?
我大概歸因為三個因素:

  1. 行動裝置普及
    • 資料傳遞速度嚴重影響效能
    • 不同平台所需的資料數量、格式都不同
  2. Domain Knowledge & Business Logic 越來越複雜
    • Schema 設計越來越複雜
    • 前後端溝通難度增加
    • Legacy API 難以處理
  3. Micro service 崛起
    • 需要一個統一的介面 (接口) 來協助整合

而 GraphQL 剛好解決以上的問題,可參考以下的架構圖:

https://imgur.com/Jdvb0fV

接下來就用幾個範例提供大家一個輪廓。

範例

範例 1 : Hello World

簡單來說, GraphQL API 提供一個 Schema (Server 維護),而 Client Side 只要輸入合法的 Query,就可以獲得所需的資料。

https://imgur.com/HeZWRal

需注意,很多人會把 Schema 跟 Query 使用的 syntax 搞混,但這兩個完全不同!

範例 2 : User Data

再來點進階的範例:假設現在有一個社交服務,需要取得目前的使用者資料:

https://imgur.com/JZOK658

可以發現 Server Response 回傳的資料都是以 JSON 格式呈現,
因此結構跟資料表達性上都十分不錯!

範例 3 : Social Network

既然是社交服務,
沒有朋友當邊緣人多可憐,
而且還得附加貼文功能才能吸引更多好友!
首先我們新增 Object Type Post 定義貼文資料結構,
再來在 User Type 添加兩個 fields: friendsposts 分別取得朋友及個人貼文的資料:

https://imgur.com/xvkDHzV

眼尖的朋友或許發現了個範例展現了 GraphQL 著名的特點: Like a graph!

有了 GraphQL ,你可以把你的商業模型 (business model) 像圖形 (graph) 一樣串連起來

不同或相同type 的資料可以串接再一起,
使得 GraphQL 只要一筆 query 就能一次拿全資料且資料格式非常有彈性!
反觀 RESTful API 同樣的資料需要多筆 request 才能拿到且格式難以調整。

以上完整的範例可以到我的 GraphQL Playground Example 玩玩,打開其中的 HISTORY 標籤可以看到 query 歷程紀錄。如下圖:
https://imgur.com/TSX2emN

如果想要看這段程式碼怎麼實現的可以參考:My Apollo Launchpad example

PS 以上幾個範例為展示用,沒辦法完全看懂很正常,但如果有興趣想完全搞懂的,請務必追蹤我未來的文章 XD

以下就來介紹幾點 GraphQL 的優點及缺點。

優點

  1. 精準資料取得

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

    相較之下 RESTful API 就需要多趟來回 (multiple round-trips) 才能拿足資料且缺乏彈性

  2. 程式即文檔

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

    這點真的讚,透過互動式的 IDE 解析 Schema 而產生的 Spec 不但一清二楚而且 UI 也很好看 XD。如圖

  3. 前端控制權提升

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

    • 不預設綁任何程式語言 (language agnostic) 或是資料庫 (DB agnostic) GitHub 經驗參考
    • 可將不同 micro service 的 GraphQL schema 串接在一起 (Schema stitching)
  5. 強型別 (Strongly Typed)

    • 型別錯就直接被擋下來
    • 支援五種基礎型別 (Scalar Types)
    • 能自定義型別如 'URL', 'TIMESTAMP', 'DATE', 'PHONE_NUMBER' 等等

缺點

  1. 過於自由、規範少

    • 沒有一定的實作規範,可能因為前後端對於架構的疏忽或不了解導致設計出過於複雜的 Schema
    • 沒有一個成熟的 Best Practice 時,容易出現 Anti Pattern
    • 不懂 GraphQL 優勢,而設計出一套「 RESTFul GraphQL 」
  2. 學習成本

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

    • GraphQL 目前還算是新的技術、仍有許多的規範及應用仍在開發中,所以需密切注意更新,不然哪一天睡覺起來發現有 breaking change 可不是開玩笑的
    • GraphQL API 主要使用 POST + json body ,所以原生不支援 multiple-part 上傳檔案
      目前僅 Apollo Server使用 streaming 方法來達到類似效果

    目前最有名的開源社群非 Apollo 莫屬,有興趣可參考看看

  4. Server Side Caching 實作困難

    • RESTful API 的 endpoint 固定且資料需求單純,然而 GraphQL 難以保證每次 request 的模樣,因此 較難實作 Caching (但還是有方法!)

如果 GraphQL 還是不夠吸引你,那我再舉個例子,使用一個 API 系統就像在百貨公司的地下美食廣場買晚餐,傳統的 RESTful API 會要求你要一家一家 (很多 route) 去點餐,耗時又費力。

為了留住客人的心,百貨公司的餐飲店家們開發出一款點餐 APP 整合各家的點餐介面,消費者只要把想點的各家食物放進菜單 (還可以選擇雞排要切不要辣),一鍵送出後就只要等待所有餐點送來桌上,省時又不費力!

使用 GraphQL 的體驗就如同使用 APP 一樣,此外通過 APP 還可以更容易取得額外資訊如餐廳的聯絡方式、營業額甚至是創業故事 XD。


其實相關優秀的 GraphQL 學習資源相當多,我將在下面一一列舉,不過中文方面比較沒有一個統合的學習整理,而之前也有前輩有做過 GraphQL 相關的鐵人賽主題,講得也非常好,不過比較偏實作路線,但我覺得 GraphQL 很多精彩的地方不在於「工具」,而是其衍生出的「理念」。
我目前任職的公司正在使用 GraphQL,但是因為之前對於 GraphQL 的認識不夠深,因此很可惜地沒有發揮GraphQL 的優勢(我們都戲稱 Restful GraphQL XD)。
因此我鐵人賽前半段介紹完這項技術的基礎後,就會開始專注在一些較為深入的主題或 Design Pattern 等等,
並且盡量顧及理論及實作。

另外如果想玩玩一些大公司的公開 GraphQL API,
可到 GraphQLHub


Reference:


學習資源:

  1. Offical GraphQL Website
  2. How To GraphQL
  3. Amazing GraphQL
  4. Apollo Medium
  5. awesome-apollo-graphql
  6. Apollo Simple Starter
  7. Shopify/graphql-design-tutorial

下一篇
GraphQL 入門:生態圈 X 工具 X 選擇
系列文
Think in GraphQL30
3

哇!寫的非常詳細,感覺跟著你的說明很快就能學會GraphQL了!

2
legopin
iT邦新手 5 級 ‧ 2018-10-16 23:14:30

很期待你接下來的這個系列, GraphQL 這個新技術實在缺少一些討論的資源

fx777 iT邦新手 5 級‧ 2018-10-16 23:49:56 檢舉

哈哈沒想到會把你釣出來 XD

0
luxprotoss
iT邦新手 5 級 ‧ 2018-11-09 12:56:33

大大您好,非常喜歡您寫的Graphql,獲益良多,只是在看的過程發現有些小地方會讓code跑不起來,請問可以在留言板直接跟大大說哪裡是需要修改的嗎?

fx777 iT邦新手 5 級‧ 2018-11-09 13:00:00 檢舉

哈囉你好~ 因為我每篇文章篇幅都有點多 XD
在時間壓力下,很容易顧及不到每篇程式碼每個細節的正確性 (但觀念基本上沒有錯)。

如果有問題,就直接在底下留言即可~我會直接用留言回覆給你~

另外在完賽後,我會花時間把整個系列的文章重新編排 + debug 一遍。

我要留言

立即登入留言