iT邦幫忙

2023 iThome 鐵人賽

DAY 10
1
Vue.js

Vue & GraphQL 探險之旅:30天,從新手村到魔王之巔系列 第 10

[Day10] GraphQL 的語言學:深入查詢語法,描述資料的藝術與結構

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20231014/20141111nmCn5qVha1.png

從客戶端或前端的角度看,當我們提及 GraphQL 的核心概念時:

GraphQL文檔 (Document)GraphQL操作 (Operation) 是兩大不可或缺的要素。
它們為開發者提供了一個與 GraphQL 伺服器互動的基礎。

摘要

本篇文章將先針對 GraphQL Document 深入探討:

  1. GraphQL Document是什麼?
  2. GraphQL DocumentGraphQL 查詢語法 的關聯?
  3. 以及最重要的,GraphQL Document 是由哪些主要元素所組成的?

透過對 GraphQL文檔 (Document) 的深入了解,開發者可以更靈活精確地描述他們所需的資料結構,從而提升整體的開發效率和資料交互的準確性。


GraphQL Document 是什麼?

GraphQL 請求字符串 (request string) 的內容被稱為 GraphQL Document,例如:

{
  post {
    id
    title
    body
  }
}

這種語法使得 GraphQL 伺服器或客戶端能夠解析和驗證請求內容。


GraphQL Document 與 GraphQL 查詢語法的關聯?

首先,讓我們瞭解這兩者的基本定義:

  • GraphQL Document

    • 包含了一組查詢、變更或訂閱的操作和片段。
    • 它代表了客戶端希望發送給 GraphQL 伺服器的請求內容。
    • 這份文檔明確地描述了客戶端期望從伺服器取得或修改的資料結構。
  • GraphQL 查詢語法

    • 如何撰寫 GraphQL Document 的規範。
    • 定義了 GraphQL Document 的正確結構、如何選擇欄位、使用變數,以及如何加入指令等細節。

簡單來說,「GraphQL 查詢語法」可以視為一套撰寫指南或語言規範,而「GraphQL Document」則是基於這些規範所撰寫出的具體內容。因此,當開發者在編寫或解讀一份 GraphQL Document 時,實質上就是在實踐 GraphQL 查詢語法的應用。


剖析 GraphQL Document 的結構

以下是一份標準的 GraphQL Document,其中包含了查詢操作:

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

事實上,GraphQL Document 是由多個元件所構成,且每個元件都有明確定義好的固定格式和用途。讓我們徐徐道來...

欄位 Field

Field 在 GraphQL Document 中代表資料結構中的一個單位或屬性。

欄位描述了一段離散的資訊,這些資訊可以是簡單的,也可以是複雜的,且與資料之間存在關聯。
https://ithelp.ithome.com.tw/upload/images/20231014/20141111hHXWZecSD8.png

  1. post:

    • 這是一個 Field,具體來說它是一個參數化的 Field,因為它帶有一個參數 id
    • post 是此查詢的入口點,代表我們想要查詢的某篇文章。
    • post 也是 Post 型別查詢的入口點
      type Post {
        id: ID!
        title: String!
        body: String
        user: User
      }
      
  2. id, title, body: 這些都是 Field,且是 Post 型別下的屬性。它們分別代表文章的 ID、標題和內容。

  3. user:

    • 這也是一個 Field,代表與該篇文章相關的使用者資訊。user 底下還有其他 Field,表示我們想要進一步查詢此使用者的某些屬性。
    • user 可以被視為 Post 型別下的一個 Field
    • user 也是 User 型別查詢的入口點
      type User {
        id: ID!
        name: String!
        email: String!
      }
      
  4. id, name, email: 這些都是 Field,且是 User 型別下的屬性。它們分別代表使用者的 ID、姓名和電子郵件地址。

以結論來說,在 GraphQL Document 中,所有的「名稱」(如 post, id, title, body, user, name, email)都是 Field。根據它們在查詢中的位置和上下文,它們可以是主查詢的入口點,也可以是某個型別下的屬性,或是某個型別的關聯資訊。

參數 Arguments

在 GraphQL Document 中,當開發者想要指定一個特定的資料集或條件性的查詢時,可以使用參數來傳遞這些具體資訊給 GraphQL 查詢或變更。例如:

query {
  post(id: 1) {
    title
  }
}

在上述查詢中,id: 1 就是傳遞給 post 查詢的一個參數,它告訴 GraphQL 伺服器:「我想要 ID 為 1 的文章的標題」。這裡的 id 是參數的名稱,而 1 是參數的值。

使用參數的好處包括:

  • 彈性查詢:允許開發者根據特定條件或需求查詢資料,讓查詢更加動態。
  • 效率提升:在伺服器端完成過濾,減少不必要的資料傳輸,只取得確實需要的資料。
  • 易於維護:明確的參數名稱和值讓結構清晰、查詢意圖更加明確,有助於開發和維護。
  • 重用查詢:不必為每個特定情況編寫新的查詢,只需更改參數值即可。
  • 增強安全性:透過嚴格的參數型別定義,防止不合法或惡意的查詢,提高系統安全性。

變數 Variables

在 GraphQL 中,Variables 允許我們將查詢中的動態值抽取出來,以獨立的方式提供,使得查詢本身保持靜態和可重用。這樣可以提高查詢的安全性,並讓查詢和變數的管理更加獨立。例如:

query GetPost($postId: ID!) {
  post(id: $postId) {
    id
    title
  }
}

在這裡,$postId 是一個變數,其型別被定義為 ID!(表示非空的 ID 型別)。

當我們希望查詢特定的文章時,可以提供以下變數值:

{
  "postId": "123"
}

這樣,查詢模板可以被重複使用,只需改變提供的變數值即可取得不同的文章。

操作名稱 Operation Name

Operation Name 在 GraphQL Document 中用來描述這次查詢或修改的「具體動作或目的」的名稱。

雖然命名對於單一請求來說不是必需的,但給予一個名稱往往非常有用。
舉例來說,在後台記錄或是除錯時,有命名可以更快速地知道這次操作的目的。特別是當一次請求中有好幾個操作時,有了操作名稱就可以清楚指出要執行哪一個。

例如,我們在同一個 GraphQL Document 中定義兩個操作,並給予它們明確的操作名稱:

query FetchPost {
  post(id: 1) {
    id
    title
  }
}

mutation UpdatePostContent {
  updatePost(id: 1, content: "新的內容") {
    id
    content
  }
}

在上述例子中,FetchPost 是 query 操作的名稱,而 UpdatePostContent 是 mutation 操作的名稱。
當我們希望執行其中一個操作時,可以使用其操作名稱來指定。

別名 Aliases

Aliases 在 GraphQL Document 中,是用來重新命名返回的字段名稱。當你在同一個查詢中多次使用同一個字段,但參數不同時,就可以透過別名來避免衝突。例如:

query {
  userA: user(id: 1) {
    name
  }
  userB: user(id: 2) {
    name
  }
}

在這裡,我們兩次查詢 user 但參數不同,透過使用 userAuserB 作為別名,可以同時獲得兩個不同的使用者名稱。

Fragments

Fragments 在 GraphQL Document 中,是用來重複使用查詢中的部分字段集合。它可以幫助我們抽取共同的字段,使查詢結構更加清晰和模組化。例如:

fragment userInfo on User {
  id
  name
  email
}

query {
  userA: user(id: 1) {
    ...userInfo
  }
  userB: user(id: 2) {
    ...userInfo
  }
}

在上述例子中,我們定義了一個名為 userInfo 的片段,並在兩次 user 查詢中重複使用它,避免了重複撰寫相同字段。這等同於:

query {
  userA: user(id: 1) {
    id
    name
    email
  }
  userB: user(id: 2) {
    id
    name
    email
  }
}

使用 Fragments 的好處,除了模組化與重用結構清晰外,還可以有以下好處:

  • 一致性:當某個字段集合在多處使用且需要改動時,只需要修改片段即可,確保各處的查詢結果保持一致性。
  • 減少錯誤:減少重複代碼可以降低因手誤引入的錯誤機率。
  • 靈活性:片段可以和其他片段組合使用,提供更高的查詢組合靈活性。

Directives

Directives 在 GraphQL 中是一種修飾符,用於動態地改變查詢的執行行為。它通常以 @ 符號開頭,並可應用於字段、片段或整個查詢操作上。

舉例:常見的內建指令有 @include@skip,可以根據變數決定是否包含某字段。

query getUserInfo($withEmail: Boolean!) {
  user {
    id
    name
    email @include(if: $withEmail)
  }
}

在這個例子中,只有當 $withEmail 變數為 true 時,email 字段才會被查詢。

有趣的是,Vue 有 Directives,GraphQL 也有 Directives,而這會不會在開發時造成混淆呢?
https://ithelp.ithome.com.tw/upload/images/20231014/201411119bt1neMhNz.png

別著急,後續的篇章我們會深入探討這一點!


Recap

今日我們深入探索了 GraphQL Document 的核心概念,理解其在 GraphQL 中的角色和結構。它建立在強型別和契約驅動的基礎之上,保障了每一次查詢的精確性和一致性。而這,正是為何 GraphQL 能夠提供高效、可預期的查詢結果,也是 GraphQL 主要優勢。

明天,我們將繼續探討另一個核心概念:GraphQL操作 (Operation),我們將繼續揭開更多 GraphQL 的神秘面紗,敬請期待!


上一篇
[Day09] 召喚伺服器:Mock GraphQL Server 與快速測試 GraphQL 技巧
下一篇
[Day11] 資料召喚術:深入淺出 GraphQL Operation 核心概念
系列文
Vue & GraphQL 探險之旅:30天,從新手村到魔王之巔31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言