SKILL.md
readonly只读
name
graphql-operations
description
编写GraphQL操作(查询、变更、片段)的最佳实践指南。在以下场景使用此技能: (1)编写GraphQL查询或变更, (2)使用片段组织操作, (3)优化数据获取模式, (4)设置类型生成或代码检查, (5)审查操作效率。
GraphQL操作指南
本指南涵盖了作为客户端开发者编写GraphQL操作(查询、变更、订阅)的最佳实践。编写良好的操作应高效、类型安全且易于维护。
操作基础
查询结构
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
}
}
变更结构
mutation CreatePost($input: CreatePostInput!) {
createPost(input: $input) {
id
title
createdAt
}
}
订阅结构
subscription OnMessageReceived($channelId: ID!) {
messageReceived(channelId: $channelId) {
id
content
sender {
id
name
}
}
}
快速参考
操作命名
| 模式 | 示例 |
|---|---|
| 查询 | GetUser, ListPosts, SearchProducts |
| 变更 | CreateUser, UpdatePost, DeleteComment |
| 订阅 | OnMessageReceived, OnUserStatusChanged |
变量语法
# 必需变量
query GetUser($id: ID!) { ... }
# 可选变量,带默认值
query ListPosts($first: Int = 20) { ... }
# 多个变量
query SearchPosts($query: String!, $status: PostStatus, $first: Int = 10) { ... }
片段语法
# 定义片段
fragment UserBasicInfo on User {
id
name
avatarUrl
}
# 使用片段
query GetUser($id: ID!) {
user(id: $id) {
...UserBasicInfo
email
}
}
指令
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)
}
}
关键原则
1. 只请求所需字段
# 好:指定字段
query GetUserName($id: ID!) {
user(id: $id) {
id
name
}
}
# 避免:过度获取
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
bio
posts {
id
title
content
comments {
id
}
}
followers {
id
name
}
# ... 许多未使用的字段
}
}
2. 为所有操作命名
# 好:命名操作
query GetUserPosts($userId: ID!) {
user(id: $userId) {
posts {
id
title
}
}
}
# 避免:匿名操作
query {
user(id: "123") {
posts {
id
title
}
}
}
3. 使用变量,而非内联值
# 好:使用变量
query GetUser($id: ID!) {
user(id: $id) {
id
name
}
}
# 避免:硬编码值
query {
user(id: "123") {
id
name
}
}
4. 将片段与组件放在一起
// 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} />;
}
参考文件
特定主题的详细文档:
基本规则
- 始终为操作命名(不要使用匿名查询/变更)
- 始终对动态值使用变量
- 始终只请求你需要的字段
- 始终为可缓存类型包含
id字段 - 绝不在操作中硬编码值
- 绝不跨文件重复字段选择
- 优先使用片段来复用字段选择
- 优先将片段与组件放在一起
- 使用描述性的操作名称反映其目的
- 对条件字段使用
@include/@skip






