Help us improve
Share bugs, ideas, or general feedback.
From godmode
Guides GraphQL API development: schema design with Relay connections and payloads, thin resolvers, N+1 detection/fixes via DataLoader, subscriptions over WebSocket/Redis, federation, query depth/complexity limits.
npx claudepluginhub arbazkhan971/godmodeHow this skill is triggered — by the user, by Claude, or both
Slash command
/godmode:graphqlThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
- User invokes `/godmode:graphql`
Designs GraphQL schemas with Apollo Federation, implements resolvers with DataLoader, and optimizes query performance. Invoke for schema design, federation directives, and real-time subscriptions.
Designs GraphQL schemas with Apollo Federation, implements resolvers using DataLoader, and optimizes query performance. Useful for schema-first design, real-time subscriptions, and query complexity analysis.
Covers GraphQL schema design, resolvers, DataLoader for N+1 prevention, federation, subscriptions, and client integration with Apollo/urql.
Share bugs, ideas, or general feedback.
/godmode:graphql# Detect GraphQL framework
grep -l "apollo-server\|graphql-yoga\|mercurius\|\
pothos\|nexus\|type-graphql\|strawberry\|gqlgen" \
package.json pyproject.toml go.mod 2>/dev/null
# Check for DataLoader usage
grep -rl "dataloader\|DataLoader" src/ 2>/dev/null
# Find schema files
find . -name "*.graphql" -o -name "*.gql" \
| head -10
GRAPHQL DISCOVERY:
Approach: SDL-first | Code-first
Framework: Apollo | Yoga | Mercurius | Pothos | gqlgen
Consumers: web app | mobile | third-party
Auth: JWT | session | API key
Federation: monolith | gateway + subgraphs
IF no DataLoader and has relations: N+1 is likely
IF no depth limit: production API is vulnerable
IF no complexity limit: one query can DoS the server
# SDL-first example
type Query {
user(id: ID!): User
users(first: Int!, after: String): UserConnection!
}
type Mutation {
createUser(input: CreateUserInput!): CreateUserPayload!
}
# Every mutation returns payload with errors array
type CreateUserPayload {
user: User
errors: [UserError!]!
}
SCHEMA RULES:
Mutations return payload types (never throw)
All lists use Relay connections (edges, pageInfo)
Input types separate from output types
Non-nullable uses ! intentionally
Enums for fixed sets, never strings
THRESHOLDS:
Max query depth: 10 levels
Max query complexity: 1000 points
Connection max first/last: 100 items
IF depth > 10: reject query
IF complexity > 1000: reject query
Resolvers are thin orchestration — no business logic. Business logic lives in service layer.
N+1 DETECTION:
| Pattern | Action |
|-----------------------------|-----------------|
| List with nested relations | Add DataLoader |
| Field resolver with DB call | Must use loader |
| 3+ levels deep query | Audit batch plan|
DATALOADER RULES:
Every relation field MUST use DataLoader.
Create loaders per-request (not global).
Batch by ID, return in same order as input.
IF query count > N+1 for list of N: DataLoader missing
IF no DataLoader imports: flag all relation resolvers
SUBSCRIPTION ARCHITECTURE:
Transport: WebSocket (graphql-ws preferred)
Pub/Sub: Redis (production) | in-memory (dev)
THRESHOLDS:
Max subscription connections: 10K per server
Heartbeat interval: 30 seconds
IF > 1 server instance: must use Redis pub/sub
IF using in-memory pub/sub in prod: fix immediately
Each subgraph owns its entities. Gateway handles query planning. Subgraphs never call each other. Run composition checks before every merge.
REQUIRED DEFENSES:
Depth limit: 10 (configurable per operation)
Complexity limit: 1000 per query
Persisted queries or allowlist in production
Rate limiting: per-client, per-operation
FIELD COSTS:
Scalar field: 1 point
Object field: 2 points
List field: first * child_cost
Connection: first * (edge_cost + node_cost)
# Run schema validation
npx graphql-inspector validate schema.graphql
# Run N+1 regression tests
npx vitest run tests/graphql/ --reporter=verbose
TESTING LAYERS:
Schema validation: buildSchema succeeds
Resolver unit: mock context, test isolation
Integration: full query execution
N+1 regression: assert query count per operation
Contract: graphql-inspector diff (breaking changes)
GRAPHQL COMPLETE:
Types: <N> objects, <M> inputs, <K> enums
Operations: <N> queries, <M> mutations, <K> subs
DataLoaders: <N> (all relation fields covered)
Performance: depth <N>, complexity <N>
Commit: "graphql: <service> — <N> types, <M> operations, DataLoaders configured"
Never ask to continue. Loop autonomously until done.
1. Framework: apollo, yoga, mercurius, pothos, gqlgen
2. Approach: *.graphql = SDL, builder imports = code
3. DataLoader: scan for imports, flag if missing
4. Performance: depth-limit, complexity config
FOR each entity (leaf first):
1. Design types, connections, inputs, payloads
2. Implement resolvers (queries + mutations)
3. Create DataLoaders for all relation fields
4. Write tests (unit + integration + N+1 count)
5. IF N+1 detected: add DataLoader, re-test
6. IF breaking change: add new field, deprecate old
POST: Add complexity/depth limits, validate schema
Print: GraphQL: {types} types, {queries} queries, {mutations} mutations, {dataloaders} DataLoaders. N+1: {status}. Depth: {N}. Verdict: {verdict}.
timestamp types queries mutations dataloaders n1_fixed status
KEEP if: schema compiles AND zero N+1
AND mutations return payloads AND limits configured
DISCARD if: N+1 detected OR mutation throws
OR breaking change without version bump
STOP when ALL of:
- Schema compiles, snapshot test passes
- All relation fields have DataLoaders
- All mutations return payload types
- Depth + complexity limits configured
- No breaking changes vs previous schema