graphql-architect by 404kidwiz/claude-supercode-skills
npx skills add https://github.com/404kidwiz/claude-supercode-skills --skill graphql-architect提供专业的 GraphQL 架构专业知识,专注于模式设计、联合模式、解析器优化和实时订阅。构建高性能、类型安全的 GraphQL API,具备 N+1 问题预防、高效缓存以及跨分布式系统的可扩展 API 网关模式。
在以下情况下调用此技能:
在以下情况下请勿调用:
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
| 因素 | 使用 GraphQL | 使用 REST |
|---|---|---|
| 客户端类型 | 具有不同需求的多个客户端 | 具有可预测需求的单一客户端 |
| 数据关系 | 高度嵌套、相互关联的数据 | 关系较少的扁平资源 |
| 过度获取 | 客户端需要不同的数据子集 | 客户端通常需要所有字段 |
| 获取不足 | 避免多次往返请求 | 单个端点提供足够数据 |
| 模式演进 | 频繁变更,需要向后兼容 | API 稳定,可接受版本控制 |
| 实时性 | 需要订阅功能 | 轮询或 Webhook 足够 |
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 + GraphQL
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
问题:N+1 查询严重影响性能
// 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 queries
解决方案:使用 DataLoader 进行批处理
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!
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
}
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
}
| 观察现象 | 为何需要升级处理 |
|---|---|
| 查询复杂度爆炸 | 无限嵌套查询导致 DoS 攻击 |
| 联合循环依赖 | 模式设计问题 |
| 10K+ 并发订阅 | 基础设施架构问题 |
| 跨 50+ 个字段的模式版本控制 | 重大变更管理问题 |
| 跨服务事务需求 | 分布式系统模式问题 |
详细技术参考:参见 REFERENCE.md
代码示例与模式:参见 EXAMPLES.md
每周安装次数
55
仓库
GitHub 星标数
42
首次出现时间
Jan 24, 2026
安全审计
安装于
opencode45
claude-code43
codex40
gemini-cli39
cursor38
github-copilot33
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.
Invoke this skill when:
Do NOT invoke when:
| 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 |
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 + GraphQL
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
Problem : N+1 queries killing performance
// 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 queries
Solution : Batch with DataLoader
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!
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
}
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
}
| 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 |
Detailed Technical Reference : See REFERENCE.md
Code Examples & Patterns: See EXAMPLES.md
Weekly Installs
55
Repository
GitHub Stars
42
First Seen
Jan 24, 2026
Security Audits
Gen Agent Trust HubPassSocketFailSnykPass
Installed on
opencode45
claude-code43
codex40
gemini-cli39
cursor38
github-copilot33