mcpField
G
graphql

graphql

github.com/pluginagentmarketplace开发240 次安装42 周前更新
代码仓库

关于 graphql

graphql 是使用 Node.js 和 Apollo Server 构建 GraphQL API 的学习 Skill,涵盖 Schema 设计、解析器、数据访问、安全、订阅、性能和测试,从入门概念延伸到进阶主题。

主要功能

  1. 01GraphQL Schema 与解析器指导
  2. 02Apollo Server 配置示例
  3. 03使用 DataLoader 缓解 N+1 问题
  4. 04身份验证与授权模式
  5. 05订阅与 Federation 主题
  6. 06测试和错误处理示例

适用场景

  1. 01学习构建 GraphQL API
  2. 02添加实时订阅
  3. 03减少 N+1 数据获取问题
  4. 04测试 GraphQL 查询与变更

安装

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

$npx skills add https://github.com/pluginagentmarketplace/custom-plugin-nodejs --skill graphql

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

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

assets/
config.yaml
schema.json
references/
GUIDE.md
PATTERNS.md
scripts/
validate.py

详细介绍

使用 Node.js 开发 GraphQL 的技能

掌握如何使用 Node.js、Apollo Server、类型安全的架构和实时订阅来构建灵活、高效的 GraphQL API。

快速入门

分 4 步构建 GraphQL API:

  1. 定义架构 - 类型、查询、变更
  2. 编写解析器 - 数据获取逻辑
  3. 设置服务 - Apollo Server 配置
  4. 连接数据 - 数据库集成

核心概念

架构定义语言(SDL)
type User {
  id: ID!
  name: String!
  email: String!
  posts: [Post!]!
}

type Post {
  id: ID!
  title: String!
  content: String
  author: User!
}

type Query {
  user(id: ID!): User
  users(limit: Int, offset: Int): [User!]!
  post(id: ID!): Post
}

type Mutation {
  createUser(input: CreateUserInput!): User!
  updateUser(id: ID!, input: UpdateUserInput!): User
  deleteUser(id: ID!): Boolean!
}

input CreateUserInput {
  name: String!
  email: String!
  password: String!
}

type Subscription {
  postCreated: Post!
}
Apollo Server 设置
const { ApolloServer } = require('@apollo/server');
const { expressMiddleware } = require('@apollo/server/express4');
const { readFileSync } = require('fs');

const typeDefs = readFileSync('./schema.graphql', 'utf-8');

const resolvers = {
  Query: {
    user: async (_, { id }, { dataSources }) => {
      return dataSources.userAPI.getUser(id);
    },
    users: async (_, { limit = 10, offset = 0 }, { dataSources }) => {
      return dataSources.userAPI.getUsers(limit, offset);
    }
  },
  Mutation: {
    createUser: async (_, { input }, { dataSources }) => {
      return dataSources.userAPI.createUser(input);
    }
  },
  User: {
    posts: async (parent, _, { dataSources }) => {
      return dataSources.postAPI.getPostsByAuthor(parent.id);
    }
  }
};

const server = new ApolloServer({ typeDefs, resolvers });
await server.start();

app.use('/graphql', express.json(), expressMiddleware(server, {
  context: async ({ req }) => ({
    user: req.user,
    dataSources: {
      userAPI: new UserAPI(),
      postAPI: new PostAPI()
    }
  })
}));

学习路径

初级(2-3 周)
  • ✅ 理解 GraphQL 概念
  • ✅ 使用 SDL 定义架构
  • ✅ 编写基础解析器
  • ✅ 查询和变更基础
中级(4-6 周)
  • ✅ 字段解析器和关系
  • ✅ 输入验证
  • ✅ 错误处理
  • ✅ 使用 DataLoader 解决 N+1 问题
高级(8-10 周)
  • ✅ 订阅(实时)
  • ✅ 身份验证和授权
  • ✅ 用于微服务的联邦
  • ✅ 性能优化

使用 DataLoader 解决 N+1 问题

const DataLoader = require('dataloader');

const createUserLoader = () =>
  new DataLoader(async (userIds) => {
    const users = await User.find({ _id: { $in: userIds } });
    const userMap = new Map(users.map(u => [u.id, u]));
    return userIds.map(id => userMap.get(id));
  });

// Use in resolver
User: {
  posts: (parent, _, { loaders }) => {
    return loaders.userLoader.load(parent.authorId);
  }
}

身份验证与授权

const { shield, rule, allow } = require('graphql-shield');

const isAuthenticated = rule()((parent, args, { user }) => {
  return user !== null;
});

const isAdmin = rule()((parent, args, { user }) => {
  return user?.role === 'admin';
});

const permissions = shield({
  Query: { '*': allow, users: isAuthenticated },
  Mutation: {
    createPost: isAuthenticated,
    deleteUser: isAdmin
  }
});

错误处理

const { ApolloError, UserInputError } = require('apollo-server-express');

class NotFoundError extends ApolloError {
  constructor(message) {
    super(message, 'NOT_FOUND');
  }
}

// In resolvers
const resolvers = {
  Query: {
    user: async (_, { id }) => {
      const user = await User.findById(id);
      if (!user) throw new NotFoundError(`User ${id} not found`);
      return user;
    }
  }
};

单元测试模板

const { createTestClient } = require('apollo-server-testing');

describe('GraphQL API', () => {
  let query, mutate;

  beforeAll(() => {
    const server = new ApolloServer({ typeDefs, resolvers });
    const testClient = createTestClient(server);
    query = testClient.query;
    mutate = testClient.mutate;
  });

  it('should return users list', async () => {
    const GET_USERS = `query { users { id name } }`;
    const res = await query({ query: GET_USERS });

    expect(res.errors).toBeUndefined();
    expect(res.data.users).toBeDefined();
  });
});

故障排除

问题原因解决方案
N+1 查询问题字段解析器使用 DataLoader
查询缓慢未缓存实现 Apollo Cache
类型错误架构不匹配使用 codegen 验证
绕过身份验证缺少防护机制使用 graphql-shield

适用场景

以下情况适合使用 GraphQL:

  • 客户端需要灵活获取数据
  • 多个客户端有不同的数据需求
  • 避免过度获取/获取不足
  • 需要实时更新
  • 无需版本控制即可演进 API

相关技能

  • Express REST API(替代方案)
  • 数据库集成(数据源)
  • JWT 身份验证(保护 API)

资源

评论

支持 Markdown