Skip to content

Instantly share code, notes, and snippets.

@hwillson
Created October 24, 2025 14:59
Show Gist options
  • Select an option

  • Save hwillson/d0b4c619b025f8ca315750ae22c805f0 to your computer and use it in GitHub Desktop.

Select an option

Save hwillson/d0b4c619b025f8ca315750ae22c805f0 to your computer and use it in GitHub Desktop.
Rover operation builder SKILL.md
name description
rover-operation-builder
Generate GraphQL operations (queries, mutations, subscriptions, fragments) using schemas fetched from Apollo GraphOS via Rover CLI. Use when the user wants to create GraphQL operations, write queries or mutations, build subscriptions, generate fragments, or needs help crafting GraphQL code based on their schema.

Rover Operation Builder Skill

This skill helps you generate proper GraphQL operations by fetching and analyzing schemas from Apollo GraphOS using the Rover CLI.

When to Use

Use this skill when the user wants to:

  • Generate GraphQL queries, mutations, or subscriptions
  • Create reusable GraphQL fragments
  • Write operations based on their actual schema
  • Understand what fields and types are available
  • Build properly typed operations with correct arguments
  • Get suggestions for related fields to include
  • Validate operation syntax against their schema

Overview

This skill combines Rover's schema fetching capabilities with GraphQL operation generation to ensure type-safe, schema-compliant operations.

Workflow:

  1. Fetch the current schema from GraphOS using Rover
  2. Parse the schema to understand available types, fields, and arguments
  3. Generate operations based on the user's natural language description
  4. Validate the operation against the schema
  5. Suggest improvements and best practices

Step 1: Fetch the Schema

Before generating operations, fetch the schema from GraphOS:

For Graphs (Monographs)

# Fetch to stdout
rover graph fetch my-graph@production

# Save to file for analysis
rover graph fetch my-graph@production --output schema.graphql

For Subgraphs (Federated)

# Fetch subgraph schema
rover subgraph fetch my-graph@production --name products

# Save to file
rover subgraph fetch my-graph@production --name products --output products-schema.graphql

Caching Strategy

To avoid repeated fetches:

  1. Save schema to a local file (e.g., schema.graphql)
  2. Reuse the cached schema for operation generation
  3. Refresh when the user indicates schema has changed
  4. Store in .claude/cache/ or project root

Step 2: Parse the Schema

After fetching, analyze the SDL to identify:

Type Definitions:

  • Object types
  • Input types
  • Enum types
  • Interface types
  • Union types
  • Scalar types

Root Types:

  • Query - Available read operations
  • Mutation - Available write operations
  • Subscription - Available real-time operations

Field Information:

  • Field names and types
  • Required vs optional fields
  • Arguments (required/optional, types)
  • Nullability
  • Lists vs single values

Step 3: Generate Operations

Create GraphQL operations based on user requests:

Query Generation

User request: "Fetch all products with their name, price, and category"

Analyze schema:

type Query {
  products: [Product!]!
}

type Product {
  id: ID!
  name: String!
  price: Float!
  category: Category!
  description: String
  inStock: Boolean!
}

type Category {
  id: ID!
  name: String!
}

Generated operation:

query GetProducts {
  products {
    id
    name
    price
    category {
      id
      name
    }
  }
}

Mutation Generation

User request: "Create a mutation to update a product's price"

Analyze schema:

type Mutation {
  updateProduct(id: ID!, input: UpdateProductInput!): Product!
}

input UpdateProductInput {
  name: String
  price: Float
  description: String
}

Generated operation:

mutation UpdateProductPrice($productId: ID!, $newPrice: Float!) {
  updateProduct(id: $productId, input: { price: $newPrice }) {
    id
    name
    price
    category {
      id
      name
    }
  }
}

Subscription Generation

User request: "Subscribe to new product updates"

Analyze schema:

type Subscription {
  productUpdated(categoryId: ID): Product!
}

Generated operation:

subscription OnProductUpdated($categoryId: ID) {
  productUpdated(categoryId: $categoryId) {
    id
    name
    price
    inStock
    category {
      id
      name
    }
  }
}

Fragment Generation

User request: "Create a reusable fragment for product details"

Generated operation:

fragment ProductDetails on Product {
  id
  name
  price
  description
  inStock
  category {
    id
    name
  }
}

# Usage in query
query GetProducts {
  products {
    ...ProductDetails
  }
}

Step 4: Operation Best Practices

When generating operations, follow these guidelines:

Always Include IDs

query GetProducts {
  products {
    id  # Always include ID for caching
    name
    price
  }
}

Use Operation Names

# Good
query GetProductById($id: ID!) {
  product(id: $id) {
    id
    name
  }
}

# Avoid
query {
  product(id: "123") {
    name
  }
}

Use Variables for Arguments

# Good
mutation UpdateProduct($id: ID!, $input: UpdateProductInput!) {
  updateProduct(id: $id, input: $input) {
    id
    name
  }
}

# Avoid
mutation {
  updateProduct(id: "123", input: { name: "New Name" }) {
    id
    name
  }
}

Request Useful Fields

Suggest fields that are commonly needed:

  • IDs for caching and references
  • Display fields (name, title, etc.)
  • Related objects that provide context
  • Timestamps (createdAt, updatedAt)

Handle Nested Types Appropriately

query GetProduct($id: ID!) {
  product(id: $id) {
    id
    name
    category {
      id
      name
      # Include category fields users likely need
    }
    reviews {
      id
      rating
      comment
      author {
        id
        name
        # Don't nest too deeply unless requested
      }
    }
  }
}

Step 5: Validation

Validate generated operations against the schema:

Check for:

  • Field existence on types
  • Correct argument names and types
  • Required arguments are provided
  • Proper nesting of selections
  • Valid variable types
  • Fragment type conditions match

Common Issues:

❌ Field doesn't exist:

query {
  products {
    id
    cost  # Should be 'price'
  }
}

❌ Missing required argument:

query {
  product {  # Missing required 'id' argument
    id
    name
  }
}

❌ Wrong variable type:

mutation UpdateProduct($id: String!) {  # Should be ID!
  updateProduct(id: $id, input: { name: "New" }) {
    id
  }
}

Common Patterns

Pagination

query GetProductsWithPagination($limit: Int!, $offset: Int!) {
  products(limit: $limit, offset: $offset) {
    id
    name
    price
  }
  productsCount
}

Filtering

query GetProductsByCategory($categoryId: ID!, $inStock: Boolean) {
  products(categoryId: $categoryId, inStock: $inStock) {
    id
    name
    price
    inStock
  }
}

Sorting

query GetProductsSorted($sortBy: ProductSortField!, $order: SortOrder!) {
  products(sortBy: $sortBy, order: $order) {
    id
    name
    price
  }
}

Conditional Fragments

query GetItems {
  items {
    id
    ... on Product {
      name
      price
    }
    ... on Service {
      name
      duration
    }
  }
}

Aliases for Multiple Queries

query GetMultipleProducts {
  product1: product(id: "1") {
    id
    name
  }
  product2: product(id: "2") {
    id
    name
  }
}

Example Workflow

User: "Help me fetch all users with their recent orders"

Steps:

  1. Fetch schema (if not cached):
rover graph fetch my-graph@production --output schema.graphql
  1. Analyze schema:
type Query {
  users: [User!]!
}

type User {
  id: ID!
  name: String!
  email: String!
  orders: [Order!]!
}

type Order {
  id: ID!
  total: Float!
  status: OrderStatus!
  createdAt: DateTime!
  items: [OrderItem!]!
}
  1. Generate operation:
query GetUsersWithRecentOrders {
  users {
    id
    name
    email
    orders {
      id
      total
      status
      createdAt
      items {
        id
        quantity
        product {
          id
          name
          price
        }
      }
    }
  }
}
  1. Suggest improvements:
  • "You might want to limit the number of orders per user"
  • "Consider adding pagination for the orders list"
  • "Add a filter for order status if you only want recent orders"
  1. Provide enhanced version:
query GetUsersWithRecentOrders($orderLimit: Int = 5, $orderStatus: [OrderStatus!]) {
  users {
    id
    name
    email
    orders(limit: $orderLimit, status: $orderStatus, orderBy: CREATED_AT_DESC) {
      id
      total
      status
      createdAt
      items {
        id
        quantity
        product {
          id
          name
          price
        }
      }
    }
  }
}

Tips for Operation Generation

  1. Start with what the user explicitly requested
  2. Add essential fields (IDs, names, display fields)
  3. Suggest related fields that might be useful
  4. Use variables for dynamic values
  5. Name operations descriptively
  6. Include fragments for repeated selections
  7. Consider pagination for list fields
  8. Validate against schema before presenting
  9. Provide usage examples with sample variables
  10. Suggest error handling fields if available

Handling Different Schema Patterns

Relay-Style Connections

query GetProductsConnection($first: Int!, $after: String) {
  products(first: $first, after: $after) {
    edges {
      cursor
      node {
        id
        name
        price
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}

Federation (Entities)

query GetProductWithReviews($representations: [_Any!]!) {
  _entities(representations: $representations) {
    ... on Product {
      id
      name
      reviews {
        id
        rating
        comment
      }
    }
  }
}

Interfaces and Unions

query GetSearchResults($query: String!) {
  search(query: $query) {
    ... on Product {
      id
      name
      price
    }
    ... on Article {
      id
      title
      publishedAt
    }
    ... on User {
      id
      name
      email
    }
  }
}

Error Handling

When schema fetch fails:

  1. Check authentication (APOLLO_KEY or rover config auth)
  2. Verify graph ref format (graph-id@variant)
  3. Confirm graph/subgraph exists in GraphOS
  4. Check network connectivity

When operation generation is unclear:

  1. Ask clarifying questions about what data is needed
  2. Show available types and fields from schema
  3. Provide examples based on similar patterns
  4. Offer multiple options if ambiguous

Related Skills

  • Use rover-schema skill to publish or check schemas
  • Use rover-dev skill for local testing of operations
  • Use rover-supergraph skill for federated schema composition

Additional Resources

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment