GraphQL 是什麼?為什麼它比 REST 更靈活?

更新日期: 2025 年 4 月 28 日

隨著前端技術的快速發展,資料需求的複雜度也越來越高。

傳統的 REST API 雖然穩定可靠,但在某些情境下卻顯得不夠靈活容易過載,甚至帶來開發效率低下的問題。

因此,一種新的資料溝通方式——GraphQL,迅速崛起,成為現代前後端溝通的新寵。

本篇文章將用最白話的方式帶你了解:

  • GraphQL 是什麼?
  • 它和 REST 的差異在哪?
  • GraphQL 的三種操作(Query、Mutation、Subscription)
  • 為什麼現代開發越來越愛用 GraphQL?

API 與 SQL 的關係與差異

在現代應用開發中,「前端」和「後端」經常需要打 API 拿資料,但資料最根本是存在哪裡呢?

答案是:資料通常存放在資料庫,而操作資料庫的語言,就是 SQL

所以,可以簡單理解成:

🔗 API 是「跟後端要資料」的橋樑,SQL 是「後端去資料庫取資料」的工具。

API 和 SQL 是不同層次的東西,但在一個完整的資料流中,它們是互相串起來的。

API 是「對外」的

  • API(Application Programming Interface)
    後端開放給前端或其他系統使用的介面
  • 它負責接收請求,例如:
  • 我要某個使用者資料
  • 我要新增一筆訂單
  • 後端收到 API 請求後,自己內部用 SQL 跟資料庫溝通,拿到資料後,再回傳給前端。

📦 可以把 API 想像成餐廳的「點餐窗口」:

  • 客人(前端)來點餐(請求)
  • 餐廳內部(後端)自己去廚房(資料庫)拿食材
  • 再把做好的餐(資料)送回給客人

SQL 是「對內」的

  • SQL(Structured Query Language)
    是一種專門操作資料庫的語言,主要用來:
  • 查資料 (SELECT)
  • 新增資料 (INSERT)
  • 更新資料 (UPDATE)
  • 刪除資料 (DELETE)
  • 只有後端工程師(或資料庫管理員)直接操作 SQL。
  • 前端看不到 SQL,通常只看到 API 回傳的資料結果。

📦 把 SQL 想像成「廚房內部的指令」:

  • 廚師(後端)根據訂單(API)去廚房(資料庫)拿東西
  • 用不同的指令(SQL)拿出食材、調整分量、做出成品

簡單流程圖

這是最常見的資料流順序:

flowchart LR
    Frontend["前端"]
    API["API 請求"]
    Backend["後端"]
    SQL["SQL 查詢"]
    Database["資料庫"]
    
    Frontend --> API
    API --> Backend
    Backend --> SQL
    SQL --> Database
    Database -->|回傳資料| Backend
    Backend -->|回傳資料| Frontend

用一個例子說明:

  • 使用者打開 App,想查詢自己的訂單
  • App 送出 API 請求:GET /orders?userId=123
  • 後端接收到後,用 SQL 查資料:
    SELECT * FROM orders WHERE user_id = 123;
  • 資料庫把訂單資料回傳給後端
  • 後端包成 JSON 格式,回傳給 App
  • App 顯示訂單資訊給使用者

什麼是 GraphQL?

GraphQL 是由 Facebook 在 2012 年提出,並於 2015 年開源的一種API 資料查詢語言(Query Language for APIs)。

它讓前端可以用一種直覺、靈活的方式向後端請資料,只拿到自己需要的資料,不多也不少。

簡單來說,GraphQL 像是:

🍱 點餐一樣,自己決定想要哪些菜色,不需要整份套餐打包。

相較於 REST 那種「一個 URL 對應一種資料格式」的設計,GraphQL 讓前端可以自訂資料內容,而不是被動接受後端給的全部資料。

GraphQL vs REST API:差在哪?

比較項目REST APIGraphQL
資料取得方式一個 endpoint = 一種資料格式一個 endpoint(通常是 /graphql)可以根據請求取得不同資料
資料冗餘問題常常拿到不需要的資料自己指定要哪些欄位
多筆資料請求可能需要多次 HTTP Request一次請求拿到所有需要的資料
文件與型別檢查需靠 API 文件或 Swagger 手動對照Schema 自帶型別與文件化,直接對照
資料更新用 POST/PUT/PATCH用 Mutation 指令完成更新

在傳統 REST API 中,我們通常需要針對不同資料設計不同的路由,例如:

  • /users/1 查詢使用者資訊
  • /posts/123 查詢文章內容

每一種資料對應一條特定的路由,路由的結構與資料緊密綁定。

而在 GraphQL 中,設計方式完全不同:

GraphQL 不是前端自己定義「路由」,而是前端自己定義「要什麼資料」。

在 GraphQL 的架構裡:

  • 後端只需要提供一個固定的端點(通常是 /graphql
  • 前端無需知道有多少路由存在
  • 取而代之的是,前端在送出請求時,直接附上一段 查詢指令(Query)
    精確描述自己想要的資料內容和欄位結構

這段 Query 會隨著請求一同送到 /graphql,由伺服器解析後,動態產生對應的資料查詢。

舉個例子

傳統 REST 可能這樣請求:

GET /users/1

而在 GraphQL 中,無論是查詢哪個使用者,都會送到同一個 /graphql,只是在內容中這樣描述:

query {
  user(id: 1) {
    name
    email
    posts {
      title
    }
  }
}

這樣的設計,帶來了極高的靈活性:

  • 前端可以自由選擇需要哪些欄位
  • 減少了後端為每個不同需求設計獨立 API 路由的負擔
  • 同一個端點即可支援各種不同資料的讀取、更新,甚至訂閱

✅ 這種「一個端點 + 動態查詢」的方式,是 GraphQL 相較於傳統 REST 更加彈性與高效的重要特點之一。


GraphQL 的三大核心操作

在 GraphQL 中,所有資料的互動,無論是查詢、更新,還是即時通訊,
都可以歸納成這三種基本操作型態:

  • Query(讀資料)
  • Mutation(改資料)
  • Subscription(即時資料)

了解這三種操作,是掌握 GraphQL 使用方法的基礎。

Query:讀取資料

✨ 什麼是 Query?

Query 就是讀取資料的動作。
你可以把它想成:

📚 「問資料庫問題,請它回你一個答案。」

  • 你可以指定想要哪一筆資料
  • 你可以選擇只拿需要的欄位
  • Server 根據你的 Query,回傳對應的資料

✅ 重點是:Query 不會改變後端的資料,只是拿資料回來。

📖 小範例:查詢使用者的基本資訊

query {
  user(id: "1") {
    name
    email
  }
}

這段 Query 的意思是:

  • 我要找 ID 是 1 的使用者
  • 但我只要他的 nameemail
  • 其他欄位(像是 createdAtpassword)一概不要

Server 回傳的資料會是這樣:

{
  "data": {
    "user": {
      "name": "Alice",
      "email": "[email protected]"
    }
  }
}

乾淨、精簡,剛好符合需求,不多也不少。

Mutation:修改資料

✨ 什麼是 Mutation?

Mutation 是用來改變資料的操作。
你可以把它想成:

✏️ 「提交新的資料,或修改、刪除現有的資料。」

常見的情境包括:

  • 新增一筆資料(例如新增一則留言)
  • 更新一筆資料(例如修改使用者的 email)
  • 刪除一筆資料(例如刪除一篇文章)

只要資料會改變,就一定要用 Mutation,而不是 Query。

📖 小範例:新增一則留言(Comment)

mutation {
  createComment(input: { text: "好文章!", postId: "123" }) {
    id
    text
    createdAt
  }
}

這段 Mutation 的意思是:

  • 呼叫 createComment 這個 Mutation API
  • 傳入一個 input 物件,包括:
  • text: 留言內容
  • postId: 這篇留言屬於哪一篇文章
  • 期待回傳新建立的留言的 idtextcreatedAt

伺服器回傳的資料可能是:

{
  "data": {
    "createComment": {
      "id": "789",
      "text": "好文章!",
      "createdAt": "2024-01-01T00:00:00Z"
    }
  }
}


Mutation 不僅會改變資料,而且可以像 Query 一樣指定回傳哪些欄位
不必回傳一整筆資料,這也是 GraphQL 的彈性之一。

Subscription:即時資料推播

✨ 什麼是 Subscription?

Subscription 是用來即時監聽資料變化的一種特殊操作。
你可以把它想成:

🔔 「訂閱某個事件,一有變化就即時通知我。」

適合的使用情境包括:

  • 聊天室新訊息推播
  • 股票報價即時更新
  • 遊戲進行中的玩家狀態變化
  • 訂單出貨狀態變更通知

✅ Subscription 會建立一條持續的連線(通常是 WebSocket)。

伺服器一有新資料,就主動推送到前端,不需要前端重複拉資料。

📖 小範例:訂閱新的訊息

subscription {
  newMessage {
    id
    content
    sender
  }
}

這段 Subscription 的意思是:

  • 監聽伺服器上的 newMessage 事件
  • 每當有新訊息產生,就即時收到推送
  • 只需要 idcontentsender 這三個欄位

當後端有新訊息時,前端會即時收到這樣的資料:

{
  "data": {
    "newMessage": {
      "id": "555",
      "content": "嗨,早安!",
      "sender": "Alice"
    }
  }
}

✅ 不需要前端主動發起查詢,資料會自動「推」過來,非常適合即時互動的場景。


GraphQL 是如何運作的?從 Schema 開始說起

在 GraphQL 中,有一個非常重要的核心觀念:

所有能做的事情,都必須先在後端定義好 Schema,前端才能使用。

這種設計方式,稱為 Schema-First

也就是說:

不論是查詢(Query)、修改(Mutation)、即時訂閱(Subscription),全部都必須事先在 Schema 中定義,才能讓前端呼叫。

這點和傳統 REST API 很不一樣。

在 REST 中,後端只要開好一條 API 路徑,前端就能去呼叫。

但在 GraphQL,Schema 就像是一份契約,明確列出:

  • 可以查哪些資料
  • 每個資料有哪些欄位
  • 可以進行哪些操作(新增、修改、刪除、訂閱)
  • 每個操作需要哪些參數,回傳什麼資料

如果 Schema 裡沒有定義,那麼即使前端寫了對應的 Query,也無法執行,伺服器會直接回傳錯誤。

具體例子:如果後端沒定義,會發生什麼事?

假設後端工程師沒有定義 createComment 這個 Mutation,但前端卻寫了這樣一段指令:

mutation {
  createComment(input: { text: "好文章!", postId: "123" }) {
    id
    text
  }
}

當這段請求送到 GraphQL Server 時,伺服器會發現:

在目前的 Schema 裡,根本不存在 createComment 這個操作。

結果伺服器會直接拒絕,並回傳錯誤訊息,像這樣:

{
  "errors": [
    {
      "message": "Cannot query field 'createComment' on type 'Mutation'.",
      "locations": [{ "line": 2, "column": 3 }]
    }
  ]
}

✅ 這就是 GraphQL 的運作規則:

前端能發送的指令,永遠必須依照後端 Schema 的定義來寫。

那麼,Schema 在整個 GraphQL 系統中扮演什麼角色?

可以這樣理解:

角色功能
Schema是整個系統的「資料目錄表」,列出所有可用的資料型別、操作方法、參數要求
GraphQL Server根據 Schema,驗證每個請求是否合法,並自動導向正確的 Resolver 執行
前端工程師必須根據 Schema,正確撰寫查詢(Query)或修改(Mutation)指令

✅ 可以說,Schema 就是前後端共同遵守的 API 契約

沒有 Schema,GraphQL 系統根本無法運作。

更直覺的比喻:GraphQL 就像點餐系統

如果把 GraphQL 開發比喻成餐廳:

  • Schema 就是菜單 ➔ 告訴你這間餐廳有什麼可以點。
  • 前端寫的 Query/Mutation 就是客人的點單 ➔ 告訴廚房想吃什麼。
  • GraphQL Server 是負責收單、檢查單、安排出餐的服務員。
  • Resolver 則是後台真正煮菜的廚師。

如果菜單上根本沒有「龍蝦義大利麵」這道菜, 就算客人在點單上寫了,也會被服務員直接打回來。

因為廚房不支援這個品項。

✅ 這就是為什麼,在 GraphQL 世界裡,Schema 永遠是第一位的。


GraphQL 為什麼越來越流行?

GraphQL 出現後,越來越多前後端團隊開始採用它來取代傳統的 REST API。

原因並不是因為 REST 不好,而是現代前端應用的需求變了,而 GraphQL 剛好很好地解決了這些新需求。

以下是 GraphQL 流行的四大主因:

資料自由選取 ➔ 減少過度請求

問題:REST API 資料量常常「不是太多,就是太少」

在傳統 REST API 設計中:

  • 一個 endpoint 回傳一整個固定格式的資料包
  • 常常有這些情況:
  • 資料太多:只想要用戶名稱,卻拿回整份用戶資料(包含密碼加密、地址、生日等用不到的欄位)
  • 資料太少:只拿到用戶基本資料,卻又要另外打一個 API 才能拿到該用戶的訂單紀錄

這樣會導致:

  • 浪費流量
  • 增加伺服器負載
  • 增加前端開發難度(要自己拼接多個 API 回來的資料)

GraphQL 的做法:前端自由挑選要的欄位

在 GraphQL 中,前端可以精確指定需要哪些欄位, 而後端只回傳這些欄位的資料。

✅ 好處:

  • 減少傳輸的資料量 ➔ 流量更小
  • 加速資料載入 ➔ 使用者體驗更順
  • 節省網路與伺服器資源

API 維護更靈活 ➔ 快速迭代

問題:REST API 維護麻煩

傳統 REST 的方式是:

  • 一個資料一條 endpoint
  • 每新增一個功能,常常就要開一條新的 API
  • 前端需求變動時(例如要多顯示一個新欄位),後端也要修改原本的 API 或新增新 API

這種做法在專案成長到一定規模後會非常痛苦:

  • API 數量暴增
  • 維護困難
  • 後端常常被迫跟著前端小改動小更新

GraphQL 的做法:一個端點,資料由前端自由選

GraphQL 通常只有一個統一的 endpoint(例如 /graphql),
前端自己在 Query 中描述要什麼資料和欄位

✅ 好處:

  • 後端 Schema 定義好資料型別就好,不用為每個需求開新 API
  • 前端可以靈活應對需求變化
  • API 維護工作量大幅減少
  • 能更快開發新功能、快速上線(快速迭代)

自帶文件、型別系統 ➔ 提高開發效率

問題:傳統 REST API 文件很容易不同步

  • API 文件通常是「額外寫的」(例如 Swagger、Notion)
  • API 一更新,文件沒跟上,前端就踩雷
  • 沒有強制型別檢查,常常發生傳錯資料格式的錯誤

GraphQL 的做法:Schema 本身就是 API 文件

GraphQL 天生具備:

  • Schema 定義型別:每個資料欄位的型別(String、Int、Object)都明確定義
  • 自動產生互動式 API 文件:像是 GraphiQL、Apollo Studio 可以直接看、直接測試 API
  • 強型別驗證:查詢不符合型別、缺少必填欄位,伺服器在開發階段就能即時報錯

✅ 好處:

  • 減少前後端溝通誤會
  • 開發時就能及早發現問題
  • 整個開發流程更順、更快

最適合複雜前端應用(像是 SPA、App)

問題:複雜畫面要打好多個 REST API

舉例來說:

  • App 的首頁同時要載入:
  • 熱門文章列表
  • 使用者個人資料
  • 通知中心未讀數
  • 商品頁要載入:
  • 商品細節
  • 商品庫存
  • 商品評論
  • 推薦商品列表

如果用傳統 REST API:

  • 要打 3~5 個以上的 HTTP 請求
  • 要等全部資料回來才能渲染頁面 ➔ 用戶覺得慢

GraphQL 的做法:一次請求,拿到全部資料

在 GraphQL 中,可以在一個 Query 裡面,同時查詢多種資料,像這樣:

query {
  me {
    name
    email
  }
  hotPosts {
    title
    likes
  }
  notifications {
    message
    read
  }
}

✅ 好處:

  • 只打一個 HTTP 請求,減少延遲
  • 一次拿回需要的所有資料
  • 頁面可以更快完整顯示出來
  • 使用者體感流暢度大幅提升

什麼時候該考慮用 GraphQL?

你可以考慮採用 GraphQL,特別是當你的專案符合以下情況時:

適用情境說明
資料結構複雜、多層巢狀需要一次拿多種類型資料,避免打太多 API
前端需求變動快想要前端能自己靈活決定資料格式,不每次都改 API
想減少多次 HTTP 請求提升效能,減少等待時間
想要提升開發效率自帶 API 文件、強型別檢查
需要即時資料推播像聊天室、通知中心等場景適合用 Subscription


如果你的應用越來越接近這些情境,GraphQL 幾乎可以說是必備技術了!

總結一句話

GraphQL 解決了現代前端應用資料量大、需求多變、即時性高的問題,因此在 SPA、App、微服務架構中越來越受到青睞。

Similar Posts

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *