SKILL.md
readonly只读
name
graphql-schema
description
遵循行业最佳实践的 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
}
# 使用输入类型的变更操作
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!]!
}
参考文件
特定主题的详细文档:
关键规则
类型设计
- 基于领域概念定义类型,而非数据存储
- 对跨类型的共享字段使用接口
- 对互斥类型使用联合类型
- 保持类型专注(单一职责)
- 避免深层嵌套 - 尽可能扁平化
字段设计
- 字段应从客户端视角命名
- 返回尽可能具体的类型
- 对昂贵字段明确说明(考虑参数)
- 使用参数进行过滤、排序、分页
变更操作设计
- 使用单一输入参数模式:
mutation(input: InputType!) - 在变更响应中返回受影响的对象
- 围绕业务操作建模变更,而非 CRUD
- 考虑返回成功/错误类型的联合
ID 策略
- 尽可能使用全局唯一 ID
- 实现
Node接口以支持重新获取 - 如果需要,对复合 ID 进行 Base64 编码
基本规则
- 始终为类型和字段添加描述
- 对不能为 null 的字段始终使用非空(!)
- 对列表始终使用 [Type!]! 模式
- 切勿在 Schema 中暴露数据库内部细节
- 未经弃用标记,切勿破坏向后兼容性
- 优先使用专用输入类型而非多个参数
- 对于固定值,优先使用枚举而非任意字符串
- 对标识符使用
ID类型,而非String或Int - 对领域特定值(DateTime、Email、URL)使用自定义标量






