mcpField
G
graphql-architect

graphql-architect

github.com/404kidwiz开发91 次安装
代码仓库

关于 graphql-architect

面向 API 开发者的 GraphQL 架构技能,涵盖模式设计、联邦、解析器优化和实时订阅。

主要功能

  1. 01类型安全的模式设计
  2. 02联邦与模式组合
  3. 03使用 DataLoader 批处理以防 N+1
  4. 04解析器缓存与查询限制
  5. 05WebSocket 订阅模式

适用场景

  1. 01设计新的 GraphQL API
  2. 02组合多个微服务的模式
  3. 03减少解析器的 N+1 查询
  4. 04添加实时订阅功能

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/404kidwiz/claude-supercode-skills --skill graphql-architect

安装后在 Claude Code 中输入/graphql-architect确认已加载。

附带文件EXAMPLES.mdREFERENCE.md

详细介绍

GraphQL 架构技能

用途

提供专业的 GraphQL 架构知识,专注于 Schema 设计、联邦模式、解析器优化和实时订阅。构建高性能、类型安全的 GraphQL API,防止 N+1 查询、实现高效缓存,并在分布式系统中采用可扩展的 API 网关模式。

适用场景

  • 从零开始为新 API 设计 GraphQL Schema
  • 在多个服务之间实现 GraphQL 联邦
  • 优化解析器,防止 N+1 查询(实现 DataLoader)
  • 使用 GraphQL 订阅构建实时功能
  • 从 REST 迁移到 GraphQL,或设计 REST+GraphQL 混合 API
  • 实现 GraphQL API 网关模式

快速开始

在以下情况下调用此技能:

  • 设计新的 GraphQL Schema 或联邦架构
  • 解决 N+1 查询性能问题
  • 实现实时订阅
  • 将 REST API 迁移到 GraphQL

以下情况不要调用:

  • 简单的 REST API 已足够(使用 api-designer)
  • 不涉及 API 层的数据库 Schema 设计(使用 database-administrator)
  • 仅处理前端数据获取(使用 frontend-developer)

核心能力

Schema 设计
  • 遵循最佳实践创建类型安全的 GraphQL Schema
  • 实现分页模式(Relay、基于偏移量)
  • 设计包含输入验证和错误处理的变更
  • 管理 Schema 演进和向后兼容性
联邦架构
  • 为微服务实现 Apollo Federation
  • 配置 Schema 拼接以组合服务
  • 管理跨服务查询和变更
  • 设置用于 Schema 组合的 API 网关
解析器优化
  • 实现 DataLoader 以防止 N+1 查询
  • 在解析器和字段级别采用缓存策略
  • 分析查询复杂度并限制深度
  • 使用持久化查询优化生产环境性能
实时订阅
  • 实现基于 WebSocket 的订阅
  • 管理订阅生命周期和清理
  • 与事件驱动的后端集成
  • 处理订阅身份验证和授权

决策框架

GraphQL 与 REST 决策矩阵
因素使用 GraphQL使用 REST
客户端类型多个客户端有不同需求单个客户端,需求可预测
数据关系高度嵌套、相互关联的数据关系较少的扁平资源
过度获取客户端需要不同的数据子集客户端通常需要所有字段
获取不足避免多次往返请求单个端点即可提供足够数据
Schema 演进频繁变更,要求向后兼容API 稳定,可接受版本控制
实时性需要订阅轮询或 Webhook 已足够
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 + GraphQL
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 实现

问题: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!

快速参考:Schema 最佳实践

分页模式(Relay 风格)
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
联邦中存在循环依赖Schema 设计问题
并发订阅数超过 10K基础设施架构问题
跨越 50+ 个字段进行 Schema 版本控制破坏性变更管理
需要跨服务事务分布式系统模式

更多资源

  • 详细技术参考:参见 REFERENCE.md

    • Apollo Federation 设置工作流
    • 字段级授权指令
    • 查询复杂度限制
  • 代码示例与模式:参见 EXAMPLES.md

    • 反模式(N+1 查询、没有复杂度限制)
    • 与其他技能的集成模式
    • 完整的解析器实现

评论

支持 Markdown