graphql-schema-generator

GraphQL Schema Generator Skill

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "graphql-schema-generator" with this command: npx skills add dexploarer/hyper-forge/dexploarer-hyper-forge-graphql-schema-generator

GraphQL Schema Generator Skill

Expert at creating GraphQL schemas with proper types, resolvers, and best practices.

When to Activate

  • "create GraphQL schema for [entity]"

  • "generate GraphQL API"

  • "build GraphQL types and resolvers"

Complete GraphQL Structure

// schema/user.schema.ts import { gql } from 'apollo-server-express';

export const userTypeDefs = gql` type User { id: ID! email: String! name: String! role: UserRole! posts: [Post!]! createdAt: DateTime! updatedAt: DateTime! }

enum UserRole { USER ADMIN MODERATOR }

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

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

type UserConnection { edges: [UserEdge!]! pageInfo: PageInfo! totalCount: Int! }

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

type Query { user(id: ID!): User users( first: Int = 10 after: String search: String ): UserConnection! me: User }

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

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

// resolvers/user.resolvers.ts import { UserInputError, AuthenticationError } from 'apollo-server-express'; import { UserService } from '../services/user.service'; import { pubsub } from '../pubsub';

const USER_CREATED = 'USER_CREATED'; const USER_UPDATED = 'USER_UPDATED';

export const userResolvers = { Query: { user: async (_parent, { id }, { services, user }) => { if (!user) { throw new AuthenticationError('Not authenticated'); }

  return await services.user.findById(id);
},

users: async (_parent, { first, after, search }, { services, user }) => {
  if (!user) {
    throw new AuthenticationError('Not authenticated');
  }

  const result = await services.user.findAll({
    first,
    after,
    search,
  });

  return {
    edges: result.users.map(user => ({
      node: user,
      cursor: Buffer.from(user.id.toString()).toString('base64'),
    })),
    pageInfo: {
      hasNextPage: result.hasNextPage,
      endCursor: result.endCursor,
    },
    totalCount: result.totalCount,
  };
},

me: async (_parent, _args, { user }) => {
  if (!user) {
    throw new AuthenticationError('Not authenticated');
  }

  return user;
},

},

Mutation: { createUser: async (_parent, { input }, { services }) => { const user = await services.user.create(input);

  // Publish subscription event
  pubsub.publish(USER_CREATED, { userCreated: user });

  return user;
},

updateUser: async (_parent, { id, input }, { services, user }) => {
  if (!user) {
    throw new AuthenticationError('Not authenticated');
  }

  if (user.id !== id && user.role !== 'ADMIN') {
    throw new AuthenticationError('Not authorized');
  }

  const updatedUser = await services.user.update(id, input);

  if (!updatedUser) {
    throw new UserInputError('User not found');
  }

  // Publish subscription event
  pubsub.publish(USER_UPDATED, {
    userUpdated: updatedUser,
    id,
  });

  return updatedUser;
},

deleteUser: async (_parent, { id }, { services, user }) => {
  if (!user || user.role !== 'ADMIN') {
    throw new AuthenticationError('Admin access required');
  }

  const success = await services.user.delete(id);

  if (!success) {
    throw new UserInputError('User not found');
  }

  return true;
},

},

Subscription: { userCreated: { subscribe: () => pubsub.asyncIterator([USER_CREATED]), },

userUpdated: {
  subscribe: withFilter(
    () => pubsub.asyncIterator([USER_UPDATED]),
    (payload, variables) => {
      return payload.id === variables.id;
    }
  ),
},

},

User: { // Field resolver for nested data posts: async (parent, _args, { services }) => { return await services.post.findByAuthorId(parent.id); }, }, };

DataLoader Pattern

// dataloaders/user.dataloader.ts import DataLoader from 'dataloader'; import { UserService } from '../services/user.service';

export function createUserLoader(userService: UserService) { return new DataLoader(async (ids: readonly string[]) => { const users = await userService.findByIds([...ids]);

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

return ids.map(id => userMap.get(id) || null);

}); }

// Use in context export const createContext = ({ req }) => { const userService = new UserService();

return { user: req.user, services: { user: userService, }, loaders: { user: createUserLoader(userService), }, }; };

Best Practices

  • Use clear, descriptive type names

  • Implement pagination (Connection pattern)

  • Add input validation

  • Use enums for fixed values

  • Implement authentication/authorization

  • Use DataLoaders to prevent N+1 queries

  • Add proper error handling

  • Document schema with descriptions

  • Version your API

  • Use subscriptions for real-time data

  • Implement field-level resolvers

  • Cache responses when appropriate

Output Checklist

  • ✅ Type definitions created

  • ✅ Resolvers implemented

  • ✅ Queries/Mutations/Subscriptions

  • ✅ DataLoaders setup

  • ✅ Authentication added

  • ✅ Error handling

  • 📝 Usage examples

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

threejs-scene-builder

No summary provided by upstream source.

Repository SourceNeeds Review
General

drizzle-migration

No summary provided by upstream source.

Repository SourceNeeds Review
General

deployment-helper

No summary provided by upstream source.

Repository SourceNeeds Review
General

api-documentation-generator

No summary provided by upstream source.

Repository SourceNeeds Review