graphql-architect
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGraphQL Architect Skill
GraphQL架构师技能
Purpose
用途
Provides expert GraphQL architecture expertise specializing in schema design, federation patterns, resolver optimization, and real-time subscriptions. Builds performant, type-safe GraphQL APIs with N+1 prevention, efficient caching, and scalable API gateway patterns across distributed systems.
提供专业的GraphQL架构技术支持,专注于Schema设计、联邦模式、解析器优化和实时订阅功能。构建高性能、类型安全的GraphQL API,包含N+1查询预防、高效缓存以及适用于分布式系统的可扩展API网关模式。
When to Use
适用场景
- Designing GraphQL schema from scratch for new APIs
- Implementing GraphQL federation across multiple services
- Optimizing resolvers to prevent N+1 queries (DataLoader implementation)
- Building real-time features with GraphQL subscriptions
- Migrating from REST to GraphQL or designing hybrid REST+GraphQL APIs
- Implementing GraphQL API gateway patterns
- 为新API从零开始设计GraphQL Schema
- 在多个服务中实现GraphQL联邦
- 优化解析器以预防N+1查询(DataLoader实现)
- 基于GraphQL订阅构建实时功能
- 从REST迁移至GraphQL,或设计REST+GraphQL混合API
- 实现GraphQL API网关模式
Quick Start
快速开始
Invoke this skill when:
- Designing new GraphQL schemas or federation architecture
- Solving N+1 query performance issues
- Implementing real-time subscriptions
- Migrating REST APIs to GraphQL
Do NOT invoke when:
- Simple REST API is sufficient (use api-designer)
- Database schema design without API layer (use database-administrator)
- Frontend data fetching only (use frontend-developer)
在以下场景调用此技能:
- 设计新的GraphQL Schema或联邦架构
- 解决N+1查询的性能问题
- 实现实时订阅功能
- 将REST API迁移至GraphQL
请勿在以下场景调用:
- 简单REST API即可满足需求(请使用api-designer)
- 仅设计数据库Schema而无需API层(请使用database-administrator)
- 仅涉及前端数据获取(请使用frontend-developer)
Core Capabilities
核心能力
Schema Design
Schema设计
- Creating type-safe GraphQL schemas with best practices
- Implementing pagination patterns (Relay, offset-based)
- Designing mutations with input validation and error handling
- Managing schema evolution and backward compatibility
- 遵循最佳实践创建类型安全的GraphQL Schema
- 实现分页模式(Relay、基于偏移量)
- 设计带输入验证和错误处理的Mutations
- 管理Schema演进与向后兼容性
Federation Architecture
联邦架构
- Implementing Apollo Federation for microservices
- Configuring schema stitching for service composition
- Managing cross-service queries and mutations
- Setting up API gateways for schema composition
- 为微服务实现Apollo Federation
- 配置Schema Stitching以实现服务组合
- 管理跨服务查询与Mutations
- 搭建用于Schema组合的API网关
Resolver Optimization
解析器优化
- Implementing DataLoader for N+1 prevention
- Caching strategies at resolver and field levels
- Query complexity analysis and depth limiting
- Persisted queries for production optimization
- 实现DataLoader以预防N+1查询
- 解析器和字段级别的缓存策略
- 查询复杂度分析与深度限制
- 生产环境下的持久化查询优化
Real-Time Subscriptions
实时订阅
- Implementing WebSocket-based subscriptions
- Managing subscription lifecycle and cleanup
- Integrating with event-driven backends
- Handling subscription authentication and authorization
- 实现基于WebSocket的订阅功能
- 管理订阅生命周期与资源清理
- 与事件驱动型后端集成
- 处理订阅的认证与授权
Decision Framework
决策框架
GraphQL vs REST Decision Matrix
GraphQL vs REST决策矩阵
| Factor | Use GraphQL | Use REST |
|---|---|---|
| Client types | Multiple clients with different needs | Single client with predictable needs |
| Data relationships | Highly nested, interconnected data | Flat resources with few relationships |
| Over-fetching | Clients need different subsets | Clients typically need all fields |
| Under-fetching | Avoid multiple round trips | Single endpoint provides enough |
| Schema evolution | Frequent changes, backward compat | Stable API, versioning acceptable |
| Real-time | Subscriptions needed | Polling or webhooks sufficient |
| 考量因素 | 选择GraphQL | 选择REST |
|---|---|---|
| 客户端类型 | 多客户端且需求各异 | 单一客户端且需求可预测 |
| 数据关系 | 高度嵌套、相互关联的数据 | 扁平化资源且关联较少 |
| 过度获取 | 客户端需要不同的数据子集 | 客户端通常需要全部字段 |
| 获取不足 | 避免多次请求往返 | 单个端点即可满足需求 |
| Schema演进 | 频繁变更且需向后兼容 | API稳定,版本化可接受 |
| 实时性 | 需要订阅功能 | 轮询或WebHook即可满足 |
Schema Design Decision Tree
Schema设计决策树
Schema Design Requirements
│
├─ Single service (monolith)?
│ └─ Schema-first design with single schema
│
├─ Multiple microservices?
│ ├─ Services owned by different teams?
│ │ └─ Apollo Federation
│ └─ Services owned by same team?
│ └─ Schema stitching (simpler)
│
├─ Existing REST APIs to wrap?
│ └─ GraphQL wrapper layer
│
└─ Need backward compatibility?
└─ Hybrid REST + GraphQLSchema设计需求
│
├─ 单一服务(单体应用)?
│ └─ 采用Schema优先设计,使用单一Schema
│
├─ 多微服务?
│ ├─ 服务由不同团队维护?
│ │ └─ 使用Apollo Federation
│ └─ 服务由同一团队维护?
│ └─ 使用Schema Stitching(更简单)
│
├─ 已有REST API需要封装?
│ └─ 搭建GraphQL封装层
│
└─ 需要向后兼容性?
└─ 采用REST+GraphQL混合架构N+1 Prevention Strategy
N+1查询预防策略
Resolver Implementation
│
├─ Field resolves to single related entity?
│ └─ DataLoader with batching
│
├─ Field resolves to list of related entities?
│ ├─ List size always small (<10)?
│ │ └─ Direct query acceptable
│ └─ List size unbounded?
│ └─ DataLoader with batching + pagination
│
├─ Nested resolvers (users → posts → comments)?
│ └─ Multi-level DataLoaders
│
└─ Aggregations or counts?
└─ Separate DataLoader for counts解析器实现
│
├─ 字段关联单个实体?
│ └─ 使用DataLoader实现批量查询
│
├─ 字段关联实体列表?
│ ├─ 列表规模始终较小(<10条)?
│ │ └─ 直接查询即可
│ └─ 列表规模无上限?
│ └─ 结合DataLoader批量查询与分页
│
├─ 嵌套解析器(用户 → 帖子 → 评论)?
│ └─ 多层级DataLoader
│
└─ 需要聚合或计数?
└─ 为计数单独配置DataLoaderCore Workflow: DataLoader Implementation
核心工作流:DataLoader实现
Problem: N+1 queries killing performance
typescript
// WITHOUT DataLoader - N+1 problem
const resolvers = {
Post: {
author: async (post, _, { db }) => {
// Executed once per post (N+1 problem!)
return db.User.findByPk(post.userId);
}
}
};
// Query for 100 posts triggers 101 DB queriesSolution: Batch with DataLoader
typescript
import DataLoader from 'dataloader';
// Create loader per request (important!)
function createLoaders(db) {
return {
userLoader: new DataLoader(async (userIds) => {
const users = await db.User.findAll({
where: { id: userIds }
});
// Return in same order as requested IDs
const userMap = new Map(users.map(u => [u.id, u]));
return userIds.map(id => userMap.get(id));
})
};
}
// Resolver using DataLoader
const resolvers = {
Post: {
author: (post, _, { loaders }) => {
return loaders.userLoader.load(post.userId);
}
}
};
// Same query now triggers 2 queries total!问题:N+1查询导致性能急剧下降
typescript
// 未使用DataLoader - 存在N+1问题
const resolvers = {
Post: {
author: async (post, _, { db }) => {
// 每个帖子执行一次查询(N+1问题!)
return db.User.findByPk(post.userId);
}
}
};
// 查询100条帖子会触发101次数据库查询解决方案:使用DataLoader实现批量查询
typescript
import DataLoader from 'dataloader';
// 每个请求创建独立的Loader(很重要!)
function createLoaders(db) {
return {
userLoader: new DataLoader(async (userIds) => {
const users = await db.User.findAll({
where: { id: userIds }
});
// 按照请求ID的顺序返回结果
const userMap = new Map(users.map(u => [u.id, u]));
return userIds.map(id => userMap.get(id));
})
};
}
// 使用DataLoader的解析器
const resolvers = {
Post: {
author: (post, _, { loaders }) => {
return loaders.userLoader.load(post.userId);
}
}
};
// 相同查询现在仅触发2次数据库查询!Quick Reference: Schema Best Practices
快速参考:Schema最佳实践
Pagination Pattern (Relay-style)
分页模式(Relay风格)
graphql
type Query {
users(first: Int, after: String, last: Int, before: String): UserConnection!
}
type UserConnection {
edges: [UserEdge!]!
pageInfo: PageInfo!
totalCount: Int!
}
type UserEdge {
node: User!
cursor: String!
}
type PageInfo {
hasNextPage: Boolean!
hasPreviousPage: Boolean!
startCursor: String
endCursor: String
}graphql
type Query {
users(first: Int, after: String, last: Int, before: String): UserConnection!
}
type UserConnection {
edges: [UserEdge!]!
pageInfo: PageInfo!
totalCount: Int!
}
type UserEdge {
node: User!
cursor: String!
}
type PageInfo {
hasNextPage: Boolean!
hasPreviousPage: Boolean!
startCursor: String
endCursor: String
}Error Handling Pattern
错误处理模式
graphql
type Mutation {
createUser(input: CreateUserInput!): CreateUserPayload!
}
type CreateUserPayload {
user: User
errors: [UserError!]!
}
type UserError {
field: String
message: String!
code: ErrorCode!
}
enum ErrorCode {
VALIDATION_ERROR
NOT_FOUND
UNAUTHORIZED
CONFLICT
}graphql
type Mutation {
createUser(input: CreateUserInput!): CreateUserPayload!
}
type CreateUserPayload {
user: User
errors: [UserError!]!
}
type UserError {
field: String
message: String!
code: ErrorCode!
}
enum ErrorCode {
VALIDATION_ERROR
NOT_FOUND
UNAUTHORIZED
CONFLICT
}Red Flags - When to Escalate
预警信号 - 需升级处理的场景
| Observation | Why Escalate |
|---|---|
| Query complexity explosion | Unbounded nested queries causing DoS |
| Federation circular dependencies | Schema design issue |
| 10K+ concurrent subscriptions | Infrastructure architecture |
| Schema versioning across 50+ fields | Breaking change management |
| Cross-service transaction needs | Distributed systems pattern |
| 现象 | 升级原因 |
|---|---|
| 查询复杂度急剧上升 | 无限制的嵌套查询可能导致拒绝服务(DoS) |
| 联邦架构出现循环依赖 | Schema设计存在问题 |
| 并发订阅数超过10000 | 涉及基础设施架构调整 |
| Schema版本变更涉及50+字段 | 需处理破坏性变更管理 |
| 跨服务事务需求 | 涉及分布式系统模式设计 |
Additional Resources
额外资源
-
Detailed Technical Reference: See REFERENCE.md
- Apollo Federation setup workflow
- Field-level authorization directives
- Query complexity limiting
-
Code Examples & Patterns: See EXAMPLES.md
- Anti-patterns (N+1 queries, no complexity limits)
- Integration patterns with other skills
- Complete resolver implementations
-
详细技术参考:查看REFERENCE.md
- Apollo Federation搭建流程
- 字段级授权指令
- 查询复杂度限制
-
代码示例与模式:查看EXAMPLES.md
- 反模式(N+1查询、无复杂度限制)
- 与其他技能的集成模式
- 完整的解析器实现示例