Token导航 LogoToken导航TokenDH.com
研究检索需要联网github未标认证来源可访问clear审计通过

graphql-developerGraphQL 开发者

Agent Skill

用于辅助 API 设计、接口文档、请求响应结构和服务集成说明。它适合让 Agent 梳理 endpoint、生成 OpenAPI 草稿、检查字段命名、整理错误码或辅助前后端联调。使用时需要确认真实业务语义、鉴权方式、分页和错误处理规则;涉及生成接口文档时,应避免凭空补字段,最好从现有代码、schema 或接口样例中提取事实。

总安装

303

周安装

13

GitHub Stars

5

下载量

106
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

3

许可证

MIT

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:graphql-developer(GraphQL 开发者)
来源仓库:https://github.com/olehsvyrydov/ai-development-team
仓库路径:skills/graphql-developer
安装命令:
npx skills add https://github.com/olehsvyrydov/ai-development-team --skill graphql-developer
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。不同来源提供的安装方式可能略有差异;本站展示可直接复制的安装命令,安装前请核对来源页面。

skills.shnpx skills
npx skills add https://github.com/olehsvyrydov/ai-development-team --skill graphql-developer

简介

用于辅助 API 设计、接口文档和前后端联调,适合梳理 endpoint 和生成 OpenAPI 草稿。

  • 适用于 GraphQL 开发和接口实现的场景。
  • 使用时需确认真实业务语义、鉴权方式和错误处理规则,避免凭空补字段。
  • 通过 GitHub 安装,支持 Codex、Claude、Cursor 和 Gemini CLI 等宿主环境。
  • 建议从现有代码、schema 或接口样例中提取事实,确保接口文档准确性。

SKILL.md

GraphQL Developer

Extends: solution-architect Type: Specialized Skill

Trigger

Use this skill alongside solution-architect when:

  • Designing GraphQL schemas
  • Implementing resolvers
  • Setting up Apollo Server
  • Configuring Apollo Federation
  • Preventing N+1 queries with DataLoader
  • Building GraphQL clients
  • Implementing subscriptions
  • Schema stitching or federation

Context

You are a Senior GraphQL Developer with 5+ years of experience building GraphQL APIs. You have designed federated schemas for microservices architectures and understand performance optimization patterns. You follow schema design best practices and implement type-safe GraphQL systems.

Expertise

Versions

TechnologyVersionNotes
GraphQL SpecOctober 2021Latest stable
Apollo Server4.xServer implementation
Apollo Federation2.xMicroservices
Apollo Client3.xReact client
GraphQL Yoga5.xAlternative server
Pothos4.xCode-first schemas

Core Concepts

Schema Design (SDL)

# schema.graphql
type Query {
  user(id: ID!): User
  users(
    first: Int
    after: String
    filter: UserFilter
  ): UserConnection!
  me: User
}

type Mutation {
  createUser(input: CreateUserInput!): CreateUserPayload!
  updateUser(id: ID!, input: UpdateUserInput!): UpdateUserPayload!
  deleteUser(id: ID!): DeleteUserPayload!
}

type Subscription {
  userCreated: User!
  userUpdated(id: ID!): User!
}

type User {
  id: ID!
  email: String!
  name: String!
  avatar: String
  role: UserRole!
  posts(first: Int, after: String): PostConnection!
  createdAt: DateTime!
  updatedAt: DateTime
}

enum UserRole {
  ADMIN
  USER
  GUEST
}

input UserFilter {
  role: UserRole
  search: String
  createdAfter: DateTime
}

input CreateUserInput {
  email: String!
  name: String!
  password: String!
  role: UserRole = USER
}

input UpdateUserInput {
  email: String
  name: String
  role: UserRole
}

# Relay-style connections
type UserConnection {
  edges: [UserEdge!]!
  pageInfo: PageInfo!
  totalCount: Int!
}

type UserEdge {
  cursor: String!
  node: User!
}

type PageInfo {
  hasNextPage: Boolean!
  hasPreviousPage: Boolean!
  startCursor: String
  endCursor: String
}

# Mutation payloads
type CreateUserPayload {
  user: User
  errors: [Error!]!
}

type UpdateUserPayload {
  user: User
  errors: [Error!]!
}

type DeleteUserPayload {
  success: Boolean!
  errors: [Error!]!
}

type Error {
  field: String
  message: String!
  code: ErrorCode!
}

enum ErrorCode {
  VALIDATION_ERROR
  NOT_FOUND
  UNAUTHORIZED
  INTERNAL_ERROR
}

scalar DateTime

Apollo Server Setup

// server.ts
import { ApolloServer } from '@apollo/server';
import { expressMiddleware } from '@apollo/server/express4';
import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';
import express from 'express';
import http from 'http';
import cors from 'cors';
import { typeDefs } from './schema';
import { resolvers } from './resolvers';
import { createContext, Context } from './context';

async function startServer() {
  const app = express();
  const httpServer = http.createServer(app);

  const server = new ApolloServer<Context>({
    typeDefs,
    resolvers,
    plugins: [
      ApolloServerPluginDrainHttpServer({ httpServer }),
    ],
  });

  await server.start();

  app.use(
    '/graphql',
    cors<cors.CorsRequest>(),
    express.json(),
    expressMiddleware(server, {
      context: createContext,
    }),
  );

  await new Promise<void>((resolve) =>
    httpServer.listen({ port: 4000 }, resolve)
  );

  console.log(`🚀 Server ready at http://localhost:4000/graphql`);
}

startServer();

Resolvers with DataLoader

// resolvers/user.ts
import { Resolvers } from '../generated/graphql';
import { Context } from '../context';

export const userResolvers: Resolvers<Context> = {
  Query: {
    user: async (_, { id }, { dataSources }) => {
      return dataSources.userLoader.load(id);
    },

    users: async (_, { first = 10, after, filter }, { dataSources }) => {
      const { users, totalCount, hasNextPage, hasPreviousPage } =
        await dataSources.userService.getUsers({ first, after, filter });

      return {
        edges: users.map((user) => ({
          cursor: Buffer.from(user.id).toString('base64'),
          node: user,
        })),
        pageInfo: {
          hasNextPage,
          hasPreviousPage,
          startCursor: users[0]
            ? Buffer.from(users[0].id).toString('base64')
            : null,
          endCursor: users[users.length - 1]
            ? Buffer.from(users[users.length - 1].id).toString('base64')
            : null,
        },
        totalCount,
      };
    },

    me: async (_, __, { user }) => {
      return user;
    },
  },

  Mutation: {
    createUser: async (_, { input }, { dataSources }) => {
      try {
        const user = await dataSources.userService.createUser(input);
        return { user, errors: [] };
      } catch (error) {
        return {
          user: null,
          errors: [{ message: error.message, code: 'VALIDATION_ERROR' }],
        };
      }
    },

    updateUser: async (_, { id, input }, { dataSources }) => {
      try {
        const user = await dataSources.userService.updateUser(id, input);
        return { user, errors: [] };
      } catch (error) {
        return {
          user: null,
          errors: [{ message: error.message, code: 'NOT_FOUND' }],
        };
      }
    },
  },

  User: {
    posts: async (parent, { first, after }, { dataSources }) => {
      return dataSources.postService.getPostsByUserId(parent.id, { first, after });
    },
  },
};

DataLoader for N+1 Prevention

// dataSources/userLoader.ts
import DataLoader from 'dataloader';
import { User } from '../models';

export function createUserLoader(db: Database) {
  return new DataLoader<string, User | null>(async (ids) => {
    const users = await db.user.findMany({
      where: { id: { in: ids as string[] } },
    });

    const userMap = new Map(users.map((user) => [user.id, user]));

    // Return in same order as requested ids
    return ids.map((id) => userMap.get(id) || null);
  });
}

// context.ts
import { createUserLoader } from './dataSources/userLoader';

export interface Context {
  user: User | null;
  dataSources: {
    userLoader: DataLoader<string, User | null>;
    userService: UserService;
    postService: PostService;
  };
}

export async function createContext({ req }): Promise<Context> {
  const token = req.headers.authorization?.replace('Bearer ', '');
  const user = token ? await verifyToken(token) : null;

  return {
    user,
    dataSources: {
      userLoader: createUserLoader(db),
      userService: new UserService(db),
      postService: new PostService(db),
    },
  };
}

Apollo Federation

# users-subgraph/schema.graphql
extend schema
  @link(url: "https://specs.apollo.dev/federation/v2.0",
        import: ["@key", "@shareable", "@external", "@provides", "@requires"])

type Query {
  user(id: ID!): User
  users: [User!]!
}

type User @key(fields: "id") {
  id: ID!
  email: String!
  name: String!
  role: UserRole!
}

# posts-subgraph/schema.graphql
extend schema
  @link(url: "https://specs.apollo.dev/federation/v2.0",
        import: ["@key", "@external"])

type Query {
  post(id: ID!): Post
  posts: [Post!]!
}

type Post @key(fields: "id") {
  id: ID!
  title: String!
  content: String!
  author: User!
}

type User @key(fields: "id") {
  id: ID! @external
  posts: [Post!]!
}

# Router configuration
# supergraph.yaml
federation_version: =2.0.0
subgraphs:
  users:
    routing_url: http://localhost:4001/graphql
    schema:
      file: ./users-subgraph/schema.graphql
  posts:
    routing_url: http://localhost:4002/graphql
    schema:
      file: ./posts-subgraph/schema.graphql

Subscriptions

// subscriptions.ts
import { PubSub } from 'graphql-subscriptions';

const pubsub = new PubSub();

export const subscriptionResolvers = {
  Subscription: {
    userCreated: {
      subscribe: () => pubsub.asyncIterator(['USER_CREATED']),
    },
    userUpdated: {
      subscribe: (_, { id }) => {
        return pubsub.asyncIterator([`USER_UPDATED_${id}`]);
      },
    },
  },
};

// In mutation resolver
export const mutationResolvers = {
  Mutation: {
    createUser: async (_, { input }, { dataSources }) => {
      const user = await dataSources.userService.createUser(input);
      pubsub.publish('USER_CREATED', { userCreated: user });
      return { user, errors: [] };
    },
  },
};

Apollo Client (React)

// client.ts
import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client';
import { setContext } from '@apollo/client/link/context';

const httpLink = createHttpLink({
  uri: 'http://localhost:4000/graphql',
});

const authLink = setContext((_, { headers }) => {
  const token = localStorage.getItem('token');
  return {
    headers: {
      ...headers,
      authorization: token ? `Bearer ${token}` : '',
    },
  };
});

export const client = new ApolloClient({
  link: authLink.concat(httpLink),
  cache: new InMemoryCache({
    typePolicies: {
      Query: {
        fields: {
          users: {
            keyArgs: ['filter'],
            merge(existing, incoming, { args }) {
              if (!args?.after) return incoming;
              return {
                ...incoming,
                edges: [...(existing?.edges || []), ...incoming.edges],
              };
            },
          },
        },
      },
    },
  }),
});

// hooks/useUsers.ts
import { useQuery, gql } from '@apollo/client';

const GET_USERS = gql`
  query GetUsers($first: Int, $after: String) {
    users(first: $first, after: $after) {
      edges {
        cursor
        node {
          id
          name
          email
        }
      }
      pageInfo {
        hasNextPage
        endCursor
      }
    }
  }
`;

export function useUsers() {
  const { data, loading, error, fetchMore } = useQuery(GET_USERS, {
    variables: { first: 10 },
  });

  const loadMore = () => {
    if (data?.users.pageInfo.hasNextPage) {
      fetchMore({
        variables: {
          after: data.users.pageInfo.endCursor,
        },
      });
    }
  };

  return { users: data?.users.edges.map((e) => e.node), loading, error, loadMore };
}

Project Structure

src/
├── schema/
│   ├── typeDefs/
│   │   ├── user.graphql
│   │   ├── post.graphql
│   │   └── index.ts
│   └── index.ts
├── resolvers/
│   ├── user.ts
│   ├── post.ts
│   └── index.ts
├── dataSources/
│   ├── userLoader.ts
│   ├── userService.ts
│   └── postService.ts
├── models/
│   ├── user.ts
│   └── post.ts
├── generated/
│   └── graphql.ts       # Generated types
├── context.ts
├── server.ts
└── codegen.ts

Parent & Related Skills

SkillRelationship
solution-architectParent skill - invoke for API architecture patterns
backend-developerFor resolver implementation, service layer
frontend-developerFor Apollo Client integration
e2e-testerFor GraphQL API testing

Standards

  • Schema-first: Define schema before resolvers
  • Relay connections: Use for pagination
  • DataLoader: Prevent N+1 queries
  • Mutation payloads: Include errors array
  • Input types: Use for mutations
  • Enums: For fixed value sets
  • Nullable defaults: Be explicit

Checklist

Before Designing Schema

  • Domain model understood
  • Query patterns identified
  • Pagination requirements clear
  • Error handling strategy

Before Deploying

  • DataLoaders implemented
  • N+1 queries eliminated
  • Query complexity limits set
  • Authentication configured
  • Schema documentation complete

Anti-Patterns to Avoid

  1. N+1 queries: Use DataLoader
  2. Overfetching: Design specific types
  3. No pagination: Always paginate lists
  4. Generic errors: Use typed error codes
  5. Missing input validation: Validate all inputs
  6. Nested mutations: Keep mutations flat
  7. No rate limiting: Implement query cost analysis

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

04

需要参考平台分布和安装热度时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

补充不同宿主或平台的使用分布数据

能力 5

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Claude Code

29.01%
按下载量换算31

trae

22.53%
按下载量换算24

Antigravity

15.68%
按下载量换算17

windsurf

13.56%
按下载量换算14

Codex

6.74%
按下载量换算7

Gemini CLI

3.67%
按下载量换算4

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。

来源信息

继续浏览同类 Skills