GraphQL 中文教學網站
🚀 從入門到實作的 GraphQL 學習頁面

GraphQL 詳細繁體中文教學網站

GraphQL 是一種 API 查詢語言與執行模型,特色是讓前端或客戶端可以「精準請求需要的資料」,避免 REST 常見的 over-fetching 與 under-fetching 問題。它的查詢能力建立在強型別 Schema 之上,並透過 Query、Mutation 等操作來讀寫資料。

精準取資料 強型別 Schema 支援欄位巢狀查詢 可用變數、片段、別名
本教學內容整理了GraphQL核心觀念,涵蓋 Queries、Schema、Mutations 與最佳實務方向,適合作為GraphQL的全方位學習。

學習重點一覽

3 核心操作類型:Query / Mutation / Subscription
9+ 重要語法與型別概念:欄位、參數、片段、變數等
3 實務範例:電商、社群、圖書系統
5 互動測驗題,立即驗收理解程度

1. 認識 GraphQL

GraphQL 的核心精神是:由客戶端描述自己要什麼資料,而不是由伺服器固定回傳整包資料。查詢可以只取所需欄位,也能一次走訪關聯物件,減少多次 API 請求。

為什麼很多人喜歡 GraphQL?

1
精準欄位選取

你只請求真正需要的欄位,例如只要使用者的 nameemail,就不必額外拿到大量不用的資料。

2
單一請求取得巢狀資料

GraphQL 可以沿著物件關係一路往下查,例如查詢使用者時,同時拿到其文章與文章留言。

3
強型別 Schema

API 能提供清楚的資料結構定義,方便前後端協作,也利於工具自動補完與文件生成。

GraphQL 與 REST 的直觀差異

比較面向 REST GraphQL
資料取得方式 依 endpoint 回傳固定格式 由客戶端宣告要哪些欄位
關聯資料 常需多次請求 可在單一查詢中巢狀取得
文件與型別 常靠額外文件維護 Schema 就是契約與型別定義
資料寫入 POST / PUT / PATCH / DELETE 透過 Mutation 執行
注意:GraphQL 很靈活,但也因此需要更重視權限、效能、快取與安全限制。

2. Schema 與型別系統

GraphQL 的 Schema 是整個 API 的契約。它描述有哪些型別、欄位、參數與回傳值。 型別系統包含 Scalar、Object、Argument、List、Non-Null、Enum、Interface、Union 與 Input Object 等核心概念。

常見型別概念

型別 說明
Scalar 純量值,例如 IntFloatStringBooleanID
Object 代表可查詢的物件,如 UserPost
Argument 欄位的參數,GraphQL 採具名參數
List [Type] 表示陣列型別
Non-Null ! 表示不可為 null,例如 String!
Enum 限制欄位值只能在固定集合中選擇
Interface 抽象型別,定義實作者都必須具備的欄位
Union 多個具體型別的聯集,不保證共享欄位
Input Object 用於 Mutation 等輸入資料結構

Schema SDL 範例

以下是使用 SDL(Schema Definition Language)撰寫的簡化範例:

type User {
  id: ID!
  name: String!
  age: Int
  role: UserRole!
  posts: [Post!]!
}

type Post {
  id: ID!
  title: String!
  content: String
  published: Boolean!
  author: User!
}

enum UserRole {
  ADMIN
  EDITOR
  MEMBER
}

input CreatePostInput {
  title: String!
  content: String
  authorId: ID!
}

type Query {
  user(id: ID!): User
  posts(keyword: String): [Post!]!
}

type Mutation {
  createPost(input: CreatePostInput!): Post!
}
重點: [Post!]! 的意思是:這是一個「不可為 null 的陣列」,而且陣列中的每個 Post 元素也不可為 null。

3. Query 查詢語法教學

Queries 教學重點包含:欄位(Fields)、參數(Arguments)、別名(Aliases)、片段(Fragments)、變數(Variables)、指令(Directives)與巢狀查詢。

3.1 最基本查詢:欄位選取

GraphQL 的核心就是「請求物件上的特定欄位」。如果欄位回傳的是物件型別,就能繼續往下巢狀選取子欄位。

query {
  user(id: "101") {
    id
    name
    age
  }
}

3.2 傳入參數 Arguments

欄位可以接受參數,讓你在單一查詢中帶入條件,例如查特定 ID、關鍵字或分頁資訊。

query {
  posts(keyword: "GraphQL") {
    id
    title
    published
  }
}

3.3 巢狀查詢

當欄位是物件或物件列表時,可以一路往下展開需要的資料,這是 GraphQL 很重要的能力。

query {
  user(id: "101") {
    name
    posts {
      title
      published
      author {
        id
        name
      }
    }
  }
}

3.4 別名 Aliases

如果同一個欄位要查兩次、但參數不同,就需要使用別名,避免回傳結果欄位名稱衝突。

query {
  adminUser: user(id: "1") {
    id
    name
  }
  normalUser: user(id: "2") {
    id
    name
  }
}

3.5 片段 Fragments

片段可以把常用欄位集合抽出重用,減少重複撰寫與維護成本。

query {
  user(id: "101") {
    ...UserBase
    posts {
      id
      title
    }
  }
}

fragment UserBase on User {
  id
  name
  role
}

3.6 變數 Variables

正式開發時,不建議手動把動態值直接串進查詢字串,而是把它們抽成變數。

query GetUser($userId: ID!) {
  user(id: $userId) {
    id
    name
    age
  }
}
{
  "userId": "101"
}

3.7 指令 Directives

GraphQL 內建常見執行指令如 @include@skip,可依條件動態決定是否包含某欄位。

query GetUser($withAge: Boolean!) {
  user(id: "101") {
    id
    name
    age @include(if: $withAge)
  }
}

3.8 初學者最常犯的錯誤

  • 回傳物件型別時,忘記再展開子欄位。
  • 同欄位多次查詢卻未使用別名。
  • 直接把動態值寫進查詢字串,而不是使用變數。
  • 沒有看 Schema 就硬寫查詢,導致欄位名稱錯誤。
小提醒:GraphQL 很自由,但自由不代表可以亂查。真實專案中常會加上深度限制、複雜度限制與權限控制。

4. Mutation 資料寫入教學

GraphQL 不只拿資料,也可以修改資料。新增、更新、刪除都通常透過 Mutation 完成。 頂層 mutation 欄位是序列執行,而不是像一般 query 欄位常見的平行解析。

4.1 新增資料

新增資料時,通常會搭配 Input Object 傳遞一組結構化輸入,然後回傳新建立的物件內容。

mutation CreatePost($input: CreatePostInput!) {
  createPost(input: $input) {
    id
    title
    published
    author {
      id
      name
    }
  }
}
{
  "input": {
    "title": "GraphQL 入門筆記",
    "content": "這是一篇 GraphQL 教學文章",
    "authorId": "101"
  }
}

4.2 更新資料

Mutation 最好設計成「用途明確」的欄位,而不是所有更新都擠在一個過度通用的欄位裡。

mutation {
  updateUserName(id: "101", name: "小美") {
    id
    name
  }
}
比起一個萬用 updateUser 接很多可選欄位,像 updateUserName 這種目的明確的設計,常更容易驗證與維護。

4.3 刪除資料

刪除資料時,常見回傳值會是被刪除的 ID,或一個 payload 物件,用來表示刪除成功。

mutation {
  deletePost(id: "501") {
    id
    success
    message
  }
}

4.4 Mutation 的重要觀念

  • 只有頂層 mutation 欄位允許造成副作用。
  • Mutation 可以包含多個欄位,但頂層欄位是依序執行。
  • 序列執行不等於資料庫交易機制,部分欄位成功、部分欄位失敗仍可能發生。
實務上若你需要真正的交易一致性,仍需在後端資料層自行處理,不能只依賴 GraphQL 本身。

5. 範例應用與實戰情境

下面用三個常見情境示範 GraphQL 的實務應用:電商平台、社群貼文系統與圖書管理系統。

範例一:電商平台

前端商品頁常需要同時拿到商品資訊、價格、庫存、評價與賣家資訊。若用 GraphQL,就能在單一請求中完整取得。

query ProductDetail($id: ID!) {
  product(id: $id) {
    id
    name
    price
    stock
    description
    seller {
      id
      shopName
      rating
    }
    reviews {
      id
      score
      comment
      user {
        id
        name
      }
    }
  }
}

適用頁面:商品詳情頁、購物車預覽頁、商品推薦區塊。

範例二:社群貼文系統

社群動態牆通常會顯示貼文作者、文字、圖片、按讚數與留言。GraphQL 很適合一次把整個畫面所需資料拿齊。

query Feed {
  posts {
    id
    content
    likeCount
    createdAt
    author {
      id
      name
      avatar
    }
    comments {
      id
      content
      author {
        id
        name
      }
    }
  }
}
mutation LikePost($postId: ID!) {
  likePost(postId: $postId) {
    id
    likeCount
  }
}

範例三:圖書管理系統

管理系統中可同時顯示書籍資料、作者資訊與借閱狀態,並能透過 Mutation 更新借閱紀錄。

query LibraryBooks {
  books {
    id
    title
    category
    available
    author {
      id
      name
    }
    currentBorrower {
      id
      name
    }
  }
}
mutation BorrowBook($bookId: ID!, $userId: ID!) {
  borrowBook(bookId: $bookId, userId: $userId) {
    id
    available
    currentBorrower {
      id
      name
    }
  }
}

前端 JavaScript 呼叫 GraphQL 範例

最簡單的方式是對 GraphQL endpoint 發送 POST,body 中包含 queryvariables

async function getUser(userId) {
  const query = `
    query GetUser($userId: ID!) {
      user(id: $userId) {
        id
        name
        age
      }
    }
  `;

  const variables = { userId };

  const res = await fetch("/graphql", {
    method: "POST",
    headers: {
      "Content-Type": "application/json"
    },
    body: JSON.stringify({ query, variables })
  });

  const result = await res.json();
  return result.data.user;
}

初學者最佳實務建議

  • 先設計清楚 Schema,再開始寫 resolver 與前端查詢。
  • 善用 Input Object 讓 Mutation 輸入更有結構。
  • 避免設計過度萬用的 Mutation,優先考慮用途明確的欄位。
  • 在大型列表查詢中加入分頁設計。
  • 從一開始就考慮授權、效能與安全限制。
  • 將業務邏輯與授權邏輯維持在清晰的分層中,不要全部塞進解析器。
最佳實務主題延伸包含:Thinking in Graphs、Serving over HTTP、Authorization、Pagination、Schema Design、Caching、Performance 與 Security。

6. GraphQL 小測驗

做做看以下題目,檢查你是否已經掌握基本概念。按下送出後會立即顯示分數與評語。

1. GraphQL 最大特色之一是什麼?

2. 哪一種語法表示「不可為 null 的字串」?

3. 如果同一欄位要查兩次但參數不同,應使用什麼?

4. 哪一個是專門用來傳遞複雜輸入資料的型別?

5. GraphQL 中新增、更新、刪除資料通常使用什麼操作?

7. 參考資料與延伸閱讀

GraphQL :Queries 查詢語法核心概念:欄位、參數、別名、片段、變數、指令與巢狀查詢。
GraphQL :Schemas and Types 型別系統重點:Scalar、Object、List、Non-Null、Enum、Interface、Union、Input Object。
GraphQL :Mutations 說明如何在 GraphQL 中進行新增、更新、刪除,以及 Mutation 的序列執行特性。
GraphQL :Best Practices 延伸主題:Thinking in Graphs、Authorization、Pagination、Performance、Security 等。
GraphQL Specification 正式規格文件,適合進一步研究語法與執行模型。