graphql-operations

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

GraphQL Operations Guide

GraphQL 操作指南

This guide covers best practices for writing GraphQL operations (queries, mutations, subscriptions) as a client developer. Well-written operations are efficient, type-safe, and maintainable.
本指南涵盖了客户端开发者编写GraphQL操作(查询、变更、订阅)的最佳实践。编写规范的操作具备高效、类型安全和易于维护的特点。

Operation Basics

操作基础

Query Structure

查询结构

graphql
query GetUser($id: ID!) {
  user(id: $id) {
    id
    name
    email
  }
}
graphql
query GetUser($id: ID!) {
  user(id: $id) {
    id
    name
    email
  }
}

Mutation Structure

变更结构

graphql
mutation CreatePost($input: CreatePostInput!) {
  createPost(input: $input) {
    id
    title
    createdAt
  }
}
graphql
mutation CreatePost($input: CreatePostInput!) {
  createPost(input: $input) {
    id
    title
    createdAt
  }
}

Subscription Structure

订阅结构

graphql
subscription OnMessageReceived($channelId: ID!) {
  messageReceived(channelId: $channelId) {
    id
    content
    sender {
      id
      name
    }
  }
}
graphql
subscription OnMessageReceived($channelId: ID!) {
  messageReceived(channelId: $channelId) {
    id
    content
    sender {
      id
      name
    }
  }
}

Quick Reference

速查参考

Operation Naming

操作命名

PatternExample
Query
GetUser
,
ListPosts
,
SearchProducts
Mutation
CreateUser
,
UpdatePost
,
DeleteComment
Subscription
OnMessageReceived
,
OnUserStatusChanged
模式示例
Query
GetUser
,
ListPosts
,
SearchProducts
Mutation
CreateUser
,
UpdatePost
,
DeleteComment
Subscription
OnMessageReceived
,
OnUserStatusChanged

Variable Syntax

变量语法

graphql
undefined
graphql
undefined

Required variable

必填变量

query GetUser($id: ID!) { ... }
query GetUser($id: ID!) { ... }

Optional variable with default

带默认值的可选变量

query ListPosts($first: Int = 20) { ... }
query ListPosts($first: Int = 20) { ... }

Multiple variables

多个变量

query SearchPosts($query: String!, $status: PostStatus, $first: Int = 10) { ... }
undefined
query SearchPosts($query: String!, $status: PostStatus, $first: Int = 10) { ... }
undefined

Fragment Syntax

片段语法

graphql
undefined
graphql
undefined

Define fragment

定义片段

fragment UserBasicInfo on User { id name avatarUrl }
fragment UserBasicInfo on User { id name avatarUrl }

Use fragment

使用片段

query GetUser($id: ID!) { user(id: $id) { ...UserBasicInfo email } }
undefined
query GetUser($id: ID!) { user(id: $id) { ...UserBasicInfo email } }
undefined

Directives

指令

graphql
query GetUser($id: ID!, $includeEmail: Boolean!) {
  user(id: $id) {
    id
    name
    email @include(if: $includeEmail)
  }
}

query GetPosts($skipDrafts: Boolean!) {
  posts {
    id
    title
    draft @skip(if: $skipDrafts)
  }
}
graphql
query GetUser($id: ID!, $includeEmail: Boolean!) {
  user(id: $id) {
    id
    name
    email @include(if: $includeEmail)
  }
}

query GetPosts($skipDrafts: Boolean!) {
  posts {
    id
    title
    draft @skip(if: $skipDrafts)
  }
}

Key Principles

核心原则

1. Request Only What You Need

1. 仅请求所需内容

graphql
undefined
graphql
undefined

Good: Specific fields

推荐:指定具体字段

query GetUserName($id: ID!) { user(id: $id) { id name } }
query GetUserName($id: ID!) { user(id: $id) { id name } }

Avoid: Over-fetching

避免:过度获取

query GetUser($id: ID!) { user(id: $id) { id name email bio posts { id title content comments { id } } followers { id name } # ... many unused fields } }
undefined
query GetUser($id: ID!) { user(id: $id) { id name email bio posts { id title content comments { id } } followers { id name } # ... 许多未使用的字段 } }
undefined

2. Name All Operations

2. 为所有操作命名

graphql
undefined
graphql
undefined

Good: Named operation

推荐:命名操作

query GetUserPosts($userId: ID!) { user(id: $userId) { posts { id title } } }
query GetUserPosts($userId: ID!) { user(id: $userId) { posts { id title } } }

Avoid: Anonymous operation

避免:匿名操作

query { user(id: "123") { posts { id title } } }
undefined
query { user(id: "123") { posts { id title } } }
undefined

3. Use Variables, Not Inline Values

3. 使用变量而非内联值

graphql
undefined
graphql
undefined

Good: Variables

推荐:使用变量

query GetUser($id: ID!) { user(id: $id) { id name } }
query GetUser($id: ID!) { user(id: $id) { id name } }

Avoid: Hardcoded values

避免:硬编码值

query { user(id: "123") { id name } }
undefined
query { user(id: "123") { id name } }
undefined

4. Colocate Fragments with Components

4. 将片段与组件放在同一位置

tsx
// UserAvatar.tsx
export const USER_AVATAR_FRAGMENT = gql`
  fragment UserAvatar on User {
    id
    name
    avatarUrl
  }
`;

function UserAvatar({ user }) {
  return <img src={user.avatarUrl} alt={user.name} />;
}
tsx
// UserAvatar.tsx
export const USER_AVATAR_FRAGMENT = gql`
  fragment UserAvatar on User {
    id
    name
    avatarUrl
  }
`;

function UserAvatar({ user }) {
  return <img src={user.avatarUrl} alt={user.name} />;
}

Reference Files

参考文档

Detailed documentation for specific topics:
  • Queries - Query patterns and optimization
  • Mutations - Mutation patterns and error handling
  • Fragments - Fragment organization and reuse
  • Variables - Variable usage and types
  • Tooling - Code generation and linting
  • 查询 - 查询模式与优化
  • 变更 - 变更模式与错误处理
  • 片段 - 片段组织与复用
  • 变量 - 变量使用与类型
  • 工具 - 代码生成与代码检查

Ground Rules

基本原则

  • ALWAYS name your operations (no anonymous queries/mutations)
  • ALWAYS use variables for dynamic values
  • ALWAYS request only the fields you need
  • ALWAYS include
    id
    field for cacheable types
  • NEVER hardcode values in operations
  • NEVER duplicate field selections across files
  • PREFER fragments for reusable field selections
  • PREFER colocating fragments with components
  • USE descriptive operation names that reflect purpose
  • USE
    @include
    /
    @skip
    for conditional fields
  • 始终为操作命名(禁止匿名查询/变更)
  • 始终为动态值使用变量
  • 始终仅请求所需字段
  • 对于可缓存类型,始终包含
    id
    字段
  • 切勿在操作中硬编码值
  • 切勿在多个文件中重复选择相同字段
  • 优先使用片段实现可复用的字段选择
  • 优先将片段与组件放在同一位置
  • 使用能体现用途的描述性操作名称
  • 使用
    @include
    /
    @skip
    处理条件字段