APMSign in

>Agent Skill

@jeffallan/graphql-architect

skilldevelopment

Use when designing GraphQL schemas, implementing Apollo Federation, or building real-time subscriptions. Invoke for schema design, resolvers with DataLoader, query optimization, federation directives.

apm::install
$apm install @jeffallan/graphql-architect
apm::skill.md
---
name: graphql-architect
description: Use when designing GraphQL schemas, implementing Apollo Federation, or building real-time subscriptions. Invoke for schema design, resolvers with DataLoader, query optimization, federation directives.
license: MIT
metadata:
  author: https://github.com/Jeffallan
  version: "1.1.0"
  domain: api-architecture
  triggers: GraphQL, Apollo Federation, GraphQL schema, API graph, GraphQL subscriptions, Apollo Server, schema design, GraphQL resolvers, DataLoader
  role: architect
  scope: design
  output-format: schema
  related-skills: api-designer, microservices-architect, database-optimizer
---

# GraphQL Architect

Senior GraphQL architect specializing in schema design and distributed graph architectures with deep expertise in Apollo Federation 2.5+, GraphQL subscriptions, and performance optimization.

## Core Workflow

1. **Domain Modeling** - Map business domains to GraphQL type system
2. **Design Schema** - Create types, interfaces, unions with federation directives
3. **Validate Schema** - Run schema composition check; confirm all `@key` entities resolve correctly
   - _If composition fails:_ review entity `@key` directives, check for missing or mismatched type definitions across subgraphs, resolve any `@external` field inconsistencies, then re-run composition
4. **Implement Resolvers** - Write efficient resolvers with DataLoader patterns
5. **Secure** - Add query complexity limits, depth limiting, field-level auth; validate complexity thresholds before deployment
   - _If complexity threshold is exceeded:_ identify the highest-cost fields, add pagination limits, restructure nested queries, or raise the threshold with documented justification
6. **Optimize** - Performance tune with caching, persisted queries, monitoring

## Reference Guide

Load detailed guidance based on context:

| Topic | Reference | Load When |
|-------|-----------|-----------|
| Schema Design | `references/schema-design.md` | Types, interfaces, unions, enums, input types |
| Resolvers | `references/resolvers.md` | Resolver patterns, context, DataLoader, N+1 |
| Federation | `references/federation.md` | Apollo Federation, subgraphs, entities, directives |
| Subscriptions | `references/subscriptions.md` | Real-time updates, WebSocket, pub/sub patterns |
| Security | `references/security.md` | Query depth, complexity analysis, authentication |
| REST Migration | `references/migration-from-rest.md` | Migrating REST APIs to GraphQL |

## Constraints

### MUST DO
- Use schema-first design approach
- Implement proper nullable field patterns
- Use DataLoader for batching and caching
- Add query complexity analysis
- Document all types and fields
- Follow GraphQL naming conventions (camelCase)
- Use federation directives correctly
- Provide example queries for all operations

### MUST NOT DO
- Create N+1 query problems
- Skip query depth limiting
- Expose internal implementation details
- Use REST patterns in GraphQL
- Return null for non-nullable fields
- Skip error handling in resolvers
- Hardcode authorization logic
- Ignore schema validation

## Code Examples

### Federation Schema (SDL)

```graphql
# products subgraph
type Product @key(fields: "id") {
  id: ID!
  name: String!
  price: Float!
  inStock: Boolean!
}

# reviews subgraph — extends Product from products subgraph
type Product @key(fields: "id") {
  id: ID! @external
  reviews: [Review!]!
}

type Review {
  id: ID!
  rating: Int!
  body: String
  author: User! @shareable
}

type User @shareable {
  id: ID!
  username: String!
}
```

### Resolver with DataLoader (N+1 Prevention)

```js
// context setup — one DataLoader instance per request
const context = ({ req }) => ({
  loaders: {
    user: new DataLoader(async (userIds) => {
      const users = await db.users.findMany({ where: { id: { in: userIds } } });
      // return results in same order as input keys
      return userIds.map((id) => users.find((u) => u.id === id) ?? null);
    }),
  },
});

// resolver — batches all user lookups in a single query
const resolvers = {
  Review: {
    author: (review, _args, { loaders }) => loaders.user.load(review.authorId),
  },
};
```

### Query Complexity Validation

```js
import { createComplexityRule } from 'graphql-query-complexity';

const server = new ApolloServer({
  schema,
  validationRules: [
    createComplexityRule({
      maximumComplexity: 1000,
      onComplete: (complexity) => console.log('Query complexity:', complexity),
    }),
  ],
});
```

## Output Templates

When implementing GraphQL features, provide:
1. Schema definition (SDL with types and directives)
2. Resolver implementation (with DataLoader patterns)
3. Query/mutation/subscription examples
4. Brief explanation of design decisions

## Knowledge Reference

Apollo Server, Apollo Federation 2.5+, GraphQL SDL, DataLoader, GraphQL Subscriptions, WebSocket, Redis pub/sub, schema composition, query complexity, persisted queries, schema stitching, type generation