graphql-schema

graphql-schema

遵循業界最佳實務設計 GraphQL Schema 的指南。使用此技能時機:(1) 設計新的 GraphQL Schema 或 API,(2) 檢視現有 Schema 以尋求改進,(3) 決定型別結構或可空性,(4) 實作分頁或錯誤模式,(5) 確保 Schema 設計的安全性。

100星標
11分支
更新於 2026/7/24
SKILL.md
唯讀
名稱
graphql-schema
描述

遵循業界最佳實務設計 GraphQL Schema 的指南。使用此技能時機:(1) 設計新的 GraphQL Schema 或 API,(2) 檢視現有 Schema 以尋求改進,(3) 決定型別結構或可空性,(4) 實作分頁或錯誤模式,(5) 確保 Schema 設計的安全性。

GraphQL Schema 設計指南

本指南涵蓋設計直觀、高效且易於維護的 GraphQL Schema 的最佳實務。Schema 設計主要是伺服器端的事項,但會直接影響 API 的可用性。

Schema 設計原則

1. 為客戶端需求設計

  • 思考客戶端會撰寫哪些查詢
  • 根據使用案例而非資料庫表格來組織型別
  • 暴露能力,而非實作細節

2. 明確表達

  • 使用清晰、描述性的名稱
  • 有意識地決定可空性
  • 使用描述文件來說明

3. 為演進設計

  • 規劃向後相容性
  • 在移除前先使用棄用標記
  • 避免破壞性變更

快速參考

型別定義語法

"""
系統中的使用者。
"""
type User {
  id: ID!
  email: String!
  name: String
  posts(first: Int = 10, after: String): PostConnection!
  createdAt: DateTime!
}

可空性規則

模式 意義
String 可空 - 可能為 null
String! 非空 - 永遠有值
[String] 可空列表,可空項目
[String!] 可空列表,非空項目
[String]! 非空列表,可空項目
[String!]! 非空列表,非空項目

最佳實務: 對列表使用 [Type!]! - 空列表優於 null,且無 null 項目。

輸入與輸出型別

# 輸出型別 - 客戶端收到的內容
type User {
  id: ID!
  email: String!
  createdAt: DateTime!
}

# 輸入型別 - 客戶端傳送的內容
input CreateUserInput {
  email: String!
  name: String
}

# 使用輸入型別的 Mutation
type Mutation {
  createUser(input: CreateUserInput!): User!
}

介面模式

interface Node {
  id: ID!
}

type User implements Node {
  id: ID!
  email: String!
}

type Post implements Node {
  id: ID!
  title: String!
}

聯合模式

union SearchResult = User | Post | Comment

type Query {
  search(query: String!): [SearchResult!]!
}

參考文件

特定主題的詳細文件:

  • 型別 - 型別設計模式、介面、聯合與自訂標量
  • 命名 - 型別、欄位與引數的命名慣例
  • 分頁 - Connection 模式與基於游標的分頁
  • 錯誤 - 錯誤建模與結果型別
  • 安全性 - Schema 設計的安全性最佳實務

關鍵規則

型別設計

  • 根據領域概念而非資料儲存來定義型別
  • 對跨型別的共用欄位使用介面
  • 對互斥的型別使用聯合
  • 保持型別專注(單一職責)
  • 避免深層巢狀 - 盡可能扁平化

欄位設計

  • 欄位應從客戶端角度命名
  • 回傳最具體的型別
  • 對昂貴的欄位明確標示(考慮使用引數)
  • 使用引數進行篩選、排序、分頁

Mutation 設計

  • 使用單一輸入引數模式:mutation(input: InputType!)
  • 在 Mutation 回應中回傳受影響的物件
  • 圍繞業務操作而非 CRUD 建模 Mutation
  • 考慮回傳成功/錯誤型別的聯合

ID 策略

  • 盡可能使用全域唯一 ID
  • 實作 Node 介面以支援重新擷取
  • 必要時對複合 ID 進行 Base64 編碼

基本規則

  • 務必為型別和欄位加上描述
  • 對不能為 null 的欄位務必使用非空(!
  • 對列表務必使用 [Type!]! 模式
  • 絕不在 Schema 中暴露資料庫內部細節
  • 絕不破壞向後相容性而不先棄用
  • 偏好使用專用輸入型別而非大量引數
  • 對固定值偏好使用列舉而非任意字串
  • 對識別碼使用 ID 型別,而非 StringInt
  • 對領域特定值(DateTime、Email、URL)使用自訂標量