graphql-schema-design

Design production-grade GraphQL schemas with best practices and patterns

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-design" with this command: npx skills add pluginagentmarketplace/custom-plugin-graphql/pluginagentmarketplace-custom-plugin-graphql-graphql-schema-design

GraphQL Schema Design Skill

Architect scalable, maintainable GraphQL APIs

Overview

Learn industry-standard patterns for designing GraphQL schemas that scale. Covers naming conventions, pagination, error handling, and schema evolution.


Quick Reference

PatternWhen to UseExample
ConnectionPaginated listsusers: UserConnection!
PayloadMutation resultsCreateUserPayload
InputMutation argsCreateUserInput
InterfaceShared fieldsinterface Node { id: ID! }
UnionMultiple typesSearchResult = User | Post

Core Patterns

1. Naming Conventions

# Types: PascalCase
type User { }
type UserProfile { }

# Fields: camelCase
type User {
  firstName: String!
  lastName: String!
  createdAt: DateTime!
  isActive: Boolean!      # Boolean prefix: is, has, can
}

# Queries: noun (singular/plural)
type Query {
  user(id: ID!): User           # Singular
  users: UserConnection!         # Plural
}

# Mutations: verb + noun
type Mutation {
  createUser(input: CreateUserInput!): CreateUserPayload!
  updateUser(id: ID!, input: UpdateUserInput!): UpdateUserPayload!
  deleteUser(id: ID!): DeleteUserPayload!

  # Actions
  sendEmail(input: SendEmailInput!): SendEmailPayload!
  publishPost(id: ID!): PublishPostPayload!
}

# Inputs: [Action][Type]Input
input CreateUserInput { }
input UpdateUserInput { }
input UserFilterInput { }

# Payloads: [Action][Type]Payload
type CreateUserPayload { }
type UpdateUserPayload { }

2. Relay-Style Pagination

# Connection pattern
type Query {
  users(
    first: Int
    after: String
    last: Int
    before: String
    filter: UserFilter
  ): UserConnection!
}

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

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

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

# Usage
query GetUsers {
  users(first: 10, after: "cursor123") {
    edges {
      node { id name }
      cursor
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}

3. Error Handling

# Payload pattern (recommended)
type CreateUserPayload {
  user: User
  errors: [UserError!]!
}

type UserError {
  field: String
  message: String!
  code: UserErrorCode!
}

enum UserErrorCode {
  INVALID_EMAIL
  DUPLICATE_EMAIL
  WEAK_PASSWORD
  NOT_FOUND
  UNAUTHORIZED
}

# Union pattern (type-safe)
union CreateUserResult =
  | CreateUserSuccess
  | ValidationError
  | NotAuthorizedError

type CreateUserSuccess {
  user: User!
}

type ValidationError {
  field: String!
  message: String!
}

type NotAuthorizedError {
  message: String!
}

type Mutation {
  createUser(input: CreateUserInput!): CreateUserResult!
}

4. Node Interface

# Global object identification
interface Node {
  id: ID!
}

type Query {
  node(id: ID!): Node
  nodes(ids: [ID!]!): [Node]!
}

type User implements Node {
  id: ID!
  name: String!
}

type Post implements Node {
  id: ID!
  title: String!
}

# Enables refetching any object by ID
query RefetchUser {
  node(id: "User:123") {
    ... on User {
      name
      email
    }
  }
}

5. Schema Organization

# schema.graphql (root)
type Query {
  # User domain
  user(id: ID!): User
  users(filter: UserFilter): UserConnection!

  # Product domain
  product(id: ID!): Product
  products(filter: ProductFilter): ProductConnection!
}

type Mutation {
  # User mutations
  createUser(input: CreateUserInput!): CreateUserPayload!
  updateUser(id: ID!, input: UpdateUserInput!): UpdateUserPayload!

  # Product mutations
  createProduct(input: CreateProductInput!): CreateProductPayload!
}

# types/user.graphql
type User implements Node {
  id: ID!
  email: String!
  name: String!
  createdAt: DateTime!
  orders: OrderConnection!
}

# types/product.graphql
type Product implements Node {
  id: ID!
  name: String!
  price: Money!
  inventory: Int!
}

Design Decisions

When to Use What

Returning a list?
├── Small fixed size (<20) → [Item!]!
└── Variable/large size → ItemConnection!

Mutation result?
├── Can have user errors → Payload pattern
└── System errors only → Direct return

Multiple possible types?
├── Completely different → Union
└── Share common fields → Interface

Nested data?
├── Always needed together → Embed
└── Sometimes needed → Separate + ID reference

Nullability Strategy

type User {
  # Always required
  id: ID!
  email: String!

  # Optional (user choice)
  nickname: String
  bio: String

  # Lists: require list, require items
  posts: [Post!]!     # Never null, items never null

  # Computed (may fail)
  avatar: String      # Nullable if generation can fail
}

Troubleshooting

IssueCauseSolution
Breaking changeRemoved fieldUse @deprecated first
Over-fetchingNo paginationAdd Connection pattern
N+1 queriesDirect relationsUse DataLoader
Type explosionToo many typesUse interfaces/generics

Schema Health Check

# Validate
npx graphql-inspector validate schema.graphql

# Check breaking changes
npx graphql-inspector diff old.graphql new.graphql

# Coverage analysis
npx graphql-inspector coverage schema.graphql queries/*.graphql

Usage

Skill("graphql-schema-design")

Related Skills

  • graphql-fundamentals - Basic types and syntax
  • graphql-resolvers - Implementing the schema
  • graphql-security - Auth-aware design

Related Agent

  • 02-graphql-schema - For detailed guidance

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.

Automation

graphql-fundamentals

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

graphql-apollo-server

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

graphql-resolvers

No summary provided by upstream source.

Repository SourceNeeds Review