← スキル一覧に戻る

graphql-schema-generator
by Dexploarer
⭐ 4🍴 2📅 2026年1月15日
SKILL.md
name: graphql-schema-generator description: Generates GraphQL schemas with type definitions, resolvers, queries, mutations, and subscriptions. Use when building GraphQL APIs.
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
スコア
総合スコア
50/100
リポジトリの品質指標に基づく評価
✓SKILL.md
SKILL.mdファイルが含まれている
+20
○LICENSE
ライセンスが設定されている
0/10
○説明文
100文字以上の説明がある
0/10
○人気
GitHub Stars 100以上
0/15
○最近の活動
3ヶ月以内に更新がある
0/10
○フォーク
10回以上フォークされている
0/5
✓Issue管理
オープンIssueが50未満
+5
✓言語
プログラミング言語が設定されている
+5
○タグ
1つ以上のタグが設定されている
0/5
レビュー
💬
レビュー機能は近日公開予定です