home / skills / ehtbanton / claudeskillsrepo / graphql-schema-generator

graphql-schema-generator skill

/graphql-schema-generator

This skill generates a complete GraphQL SDL schema with types, queries, mutations, subscriptions, and resolvers for API development.

npx playbooks add skill ehtbanton/claudeskillsrepo --skill graphql-schema-generator

Review the files below or copy the command above to add this skill to your agents.

Files (2)
SKILL.md
10.9 KB
---
name: graphql-schema-generator
description: Generate GraphQL schema definition files (SDL) with types, queries, mutations, subscriptions, and resolvers for API development. Triggers on "create GraphQL schema", "generate GraphQL types", "GraphQL API for", "SDL schema".
---

# GraphQL Schema Generator

Generate complete GraphQL Schema Definition Language (SDL) files with types, queries, mutations, and subscriptions.

## Output Requirements

**File Output:** `schema.graphql` or `schema.gql`
**Format:** GraphQL SDL (Schema Definition Language)
**Standards:** GraphQL June 2018 or later spec

## When Invoked

Immediately generate a complete, valid GraphQL schema. Include appropriate types, queries, mutations, and input types for the domain.

## SDL Structure

```graphql
# Type definitions
type TypeName {
  field: Type
}

# Input types for mutations
input InputTypeName {
  field: Type
}

# Queries (read operations)
type Query {
  resource: Type
}

# Mutations (write operations)
type Mutation {
  createResource(input: InputType): Type
}

# Subscriptions (real-time)
type Subscription {
  resourceUpdated: Type
}
```

## Complete Templates

### Blog/CMS Schema
```graphql
# ===========================================
# Scalar Types
# ===========================================

scalar DateTime
scalar UUID

# ===========================================
# Enums
# ===========================================

enum PostStatus {
  DRAFT
  PUBLISHED
  ARCHIVED
}

enum SortOrder {
  ASC
  DESC
}

enum UserRole {
  ADMIN
  EDITOR
  AUTHOR
  READER
}

# ===========================================
# Interfaces
# ===========================================

interface Node {
  id: ID!
}

interface Timestamped {
  createdAt: DateTime!
  updatedAt: DateTime!
}

# ===========================================
# Types
# ===========================================

type User implements Node & Timestamped {
  id: ID!
  email: String!
  username: String!
  displayName: String
  avatar: String
  bio: String
  role: UserRole!
  posts(first: Int, after: String, status: PostStatus): PostConnection!
  comments(first: Int, after: String): CommentConnection!
  createdAt: DateTime!
  updatedAt: DateTime!
}

type Post implements Node & Timestamped {
  id: ID!
  title: String!
  slug: String!
  content: String!
  excerpt: String
  featuredImage: String
  status: PostStatus!
  author: User!
  categories: [Category!]!
  tags: [Tag!]!
  comments(first: Int, after: String): CommentConnection!
  commentCount: Int!
  viewCount: Int!
  publishedAt: DateTime
  createdAt: DateTime!
  updatedAt: DateTime!
}

type Comment implements Node & Timestamped {
  id: ID!
  content: String!
  author: User!
  post: Post!
  parent: Comment
  replies(first: Int, after: String): CommentConnection!
  createdAt: DateTime!
  updatedAt: DateTime!
}

type Category implements Node {
  id: ID!
  name: String!
  slug: String!
  description: String
  parent: Category
  children: [Category!]!
  posts(first: Int, after: String): PostConnection!
  postCount: Int!
}

type Tag implements Node {
  id: ID!
  name: String!
  slug: String!
  posts(first: Int, after: String): PostConnection!
  postCount: Int!
}

# ===========================================
# Connection Types (Relay-style Pagination)
# ===========================================

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

type PostConnection {
  edges: [PostEdge!]!
  pageInfo: PageInfo!
  totalCount: Int!
}

type PostEdge {
  node: Post!
  cursor: String!
}

type CommentConnection {
  edges: [CommentEdge!]!
  pageInfo: PageInfo!
  totalCount: Int!
}

type CommentEdge {
  node: Comment!
  cursor: String!
}

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

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

# ===========================================
# Input Types
# ===========================================

input CreatePostInput {
  title: String!
  content: String!
  excerpt: String
  featuredImage: String
  status: PostStatus = DRAFT
  categoryIds: [ID!]
  tagNames: [String!]
}

input UpdatePostInput {
  title: String
  content: String
  excerpt: String
  featuredImage: String
  status: PostStatus
  categoryIds: [ID!]
  tagNames: [String!]
}

input CreateCommentInput {
  postId: ID!
  parentId: ID
  content: String!
}

input UpdateCommentInput {
  content: String!
}

input CreateCategoryInput {
  name: String!
  description: String
  parentId: ID
}

input PostFilterInput {
  status: PostStatus
  authorId: ID
  categoryId: ID
  tagId: ID
  search: String
}

input PostOrderInput {
  field: PostOrderField!
  direction: SortOrder!
}

enum PostOrderField {
  CREATED_AT
  UPDATED_AT
  PUBLISHED_AT
  TITLE
  VIEW_COUNT
}

# ===========================================
# Queries
# ===========================================

type Query {
  # User queries
  me: User
  user(id: ID!): User
  userByUsername(username: String!): User
  users(
    first: Int
    after: String
    role: UserRole
  ): UserConnection!

  # Post queries
  post(id: ID!): Post
  postBySlug(slug: String!): Post
  posts(
    first: Int
    after: String
    filter: PostFilterInput
    orderBy: PostOrderInput
  ): PostConnection!

  # Search
  searchPosts(query: String!, first: Int, after: String): PostConnection!

  # Category queries
  category(id: ID!): Category
  categoryBySlug(slug: String!): Category
  categories(parentId: ID): [Category!]!

  # Tag queries
  tag(id: ID!): Tag
  tagBySlug(slug: String!): Tag
  tags(first: Int): [Tag!]!
  popularTags(limit: Int = 10): [Tag!]!

  # Comment queries
  comment(id: ID!): Comment
}

# ===========================================
# Mutations
# ===========================================

type Mutation {
  # Auth mutations
  login(email: String!, password: String!): AuthPayload!
  register(email: String!, username: String!, password: String!): AuthPayload!
  logout: Boolean!
  refreshToken(refreshToken: String!): AuthPayload!

  # User mutations
  updateProfile(
    displayName: String
    bio: String
    avatar: String
  ): User!
  changePassword(currentPassword: String!, newPassword: String!): Boolean!

  # Post mutations
  createPost(input: CreatePostInput!): Post!
  updatePost(id: ID!, input: UpdatePostInput!): Post!
  deletePost(id: ID!): Boolean!
  publishPost(id: ID!): Post!
  unpublishPost(id: ID!): Post!

  # Comment mutations
  createComment(input: CreateCommentInput!): Comment!
  updateComment(id: ID!, input: UpdateCommentInput!): Comment!
  deleteComment(id: ID!): Boolean!

  # Category mutations (admin only)
  createCategory(input: CreateCategoryInput!): Category!
  updateCategory(id: ID!, name: String, description: String): Category!
  deleteCategory(id: ID!): Boolean!

  # Tag mutations
  createTag(name: String!): Tag!
  deleteTag(id: ID!): Boolean!
}

# ===========================================
# Subscriptions
# ===========================================

type Subscription {
  postPublished: Post!
  commentAdded(postId: ID!): Comment!
  postUpdated(id: ID!): Post!
}

# ===========================================
# Payload Types
# ===========================================

type AuthPayload {
  accessToken: String!
  refreshToken: String!
  expiresIn: Int!
  user: User!
}

# ===========================================
# Directives
# ===========================================

directive @auth(requires: UserRole = READER) on FIELD_DEFINITION
directive @deprecated(reason: String) on FIELD_DEFINITION
```

### E-commerce Schema
```graphql
scalar DateTime
scalar Decimal
scalar JSON

enum OrderStatus {
  PENDING
  CONFIRMED
  PROCESSING
  SHIPPED
  DELIVERED
  CANCELLED
  REFUNDED
}

enum PaymentStatus {
  PENDING
  COMPLETED
  FAILED
  REFUNDED
}

type Product implements Node {
  id: ID!
  sku: String!
  name: String!
  slug: String!
  description: String
  price: Decimal!
  compareAtPrice: Decimal
  images: [ProductImage!]!
  category: Category
  variants: [ProductVariant!]!
  inventory: Int!
  isAvailable: Boolean!
  attributes: JSON
  createdAt: DateTime!
  updatedAt: DateTime!
}

type ProductVariant {
  id: ID!
  name: String!
  sku: String!
  price: Decimal!
  inventory: Int!
  attributes: JSON
}

type ProductImage {
  id: ID!
  url: String!
  altText: String
  isPrimary: Boolean!
}

type Cart {
  id: ID!
  items: [CartItem!]!
  subtotal: Decimal!
  tax: Decimal!
  shipping: Decimal!
  total: Decimal!
  itemCount: Int!
}

type CartItem {
  id: ID!
  product: Product!
  variant: ProductVariant
  quantity: Int!
  unitPrice: Decimal!
  total: Decimal!
}

type Order implements Node {
  id: ID!
  orderNumber: String!
  customer: Customer!
  items: [OrderItem!]!
  status: OrderStatus!
  paymentStatus: PaymentStatus!
  subtotal: Decimal!
  tax: Decimal!
  shipping: Decimal!
  discount: Decimal!
  total: Decimal!
  shippingAddress: Address!
  billingAddress: Address!
  notes: String
  createdAt: DateTime!
  updatedAt: DateTime!
}

input AddToCartInput {
  productId: ID!
  variantId: ID
  quantity: Int!
}

input CheckoutInput {
  shippingAddressId: ID!
  billingAddressId: ID
  paymentMethodId: ID!
  notes: String
}

type Query {
  # Products
  product(id: ID, slug: String): Product
  products(
    first: Int
    after: String
    categoryId: ID
    search: String
    minPrice: Decimal
    maxPrice: Decimal
  ): ProductConnection!

  # Cart
  cart: Cart

  # Orders
  order(id: ID!): Order
  orders(first: Int, after: String, status: OrderStatus): OrderConnection!
}

type Mutation {
  # Cart
  addToCart(input: AddToCartInput!): Cart!
  updateCartItem(itemId: ID!, quantity: Int!): Cart!
  removeFromCart(itemId: ID!): Cart!
  clearCart: Cart!

  # Checkout
  checkout(input: CheckoutInput!): Order!

  # Orders
  cancelOrder(id: ID!, reason: String): Order!
}

type Subscription {
  orderStatusChanged(orderId: ID!): Order!
}
```

## Best Practices

### Naming Conventions
- Types: PascalCase (`User`, `BlogPost`)
- Fields: camelCase (`firstName`, `createdAt`)
- Enums: SCREAMING_SNAKE_CASE (`PENDING`, `IN_PROGRESS`)
- Inputs: PascalCase with Input suffix (`CreateUserInput`)

### Nullable vs Non-Null
```graphql
# Non-null (required)
field: String!

# Nullable (optional)
field: String

# Non-null list of non-null items
field: [String!]!

# Nullable list of nullable items
field: [String]
```

## Validation Checklist

Before outputting, verify:
- [ ] All types referenced exist
- [ ] Query type has at least one field
- [ ] Input types use only scalar, enum, or other input types
- [ ] No circular references in non-null fields
- [ ] Pagination follows Relay spec (if used)
- [ ] Naming conventions are consistent
- [ ] Descriptions added for complex fields

## Example Invocations

**Prompt:** "Create GraphQL schema for a task management app"
**Output:** Complete `schema.graphql` with tasks, projects, users, assignments.

**Prompt:** "Generate GraphQL types for social media API"
**Output:** Complete `schema.graphql` with users, posts, followers, likes, comments.

**Prompt:** "GraphQL schema for inventory management system"
**Output:** Complete `schema.graphql` with products, warehouses, stock, transfers.

Overview

This skill generates complete GraphQL Schema Definition Language (SDL) files for API development, including types, queries, mutations, subscriptions, and resolver signatures. It produces ready-to-use schema.graphql/schema.gql that follow the GraphQL spec and common conventions. Use it to scaffold domains quickly with validated input types, enums, pagination, and subscription hooks.

How this skill works

When triggered by intents like "create GraphQL schema" or "generate GraphQL types", the skill builds a full SDL file tailored to the requested domain. It emits scalar definitions, enums, interfaces, types, input types, Query/Mutation/Subscription blocks, connection types for pagination, and directive skeletons. The output is validated against a checklist: referenced types exist, queries present, input-only usage for input types, and no non-null circulars.

When to use it

  • Scaffolding a new API schema for a product, blog, e-commerce, or internal tool
  • Generating domain-specific SDL from a short prompt (e.g., task manager, social network)
  • Creating consistent input types and mutations for CRUD operations
  • Adding subscriptions and payload types for real-time features
  • Producing Relay-style connection types for cursor pagination

Best practices

  • Follow naming conventions: PascalCase for types and inputs, camelCase for fields, SCREAMING_SNAKE_CASE for enum values
  • Prefer input types for mutation payloads and avoid referencing object types inside input blocks
  • Use non-null judiciously: mark required fields as '!' but avoid non-null circular references
  • Include PageInfo and Connection types when offering cursor-based pagination
  • Add brief descriptions to complex fields and enforce a validation checklist before finalizing

Example use cases

  • Create GraphQL schema for a blog/CMS with posts, users, comments, categories, and tags
  • Generate GraphQL types for an e-commerce platform with products, carts, orders, and payments
  • Produce SDL for a task management app: tasks, projects, assignments, and activity feeds
  • Build schema for a social media API including users, posts, follows, likes, and comments
  • Scaffold inventory system schema with products, warehouses, stock levels, and transfers

FAQ

What file and format will the skill produce?

It outputs a single SDL file named schema.graphql or schema.gql following GraphQL SDL syntax.

Does the generated schema include pagination and subscriptions?

Yes. The skill can include Relay-style connection types for pagination and Subscription types for real-time updates when requested.