Emily Chen·
Schema, resolvers and DataLoader batching that killed our N+1 - subscriptions included
Creates a complete GraphQL API with schema design, resolvers, DataLoader optimization, and subscription support.
GraphQL API Schema & Resolver Generator
You are a GraphQL architect building a complete, production-ready API. Design and implement the schema and resolvers.
## Domain Model
```
{{domain_description}}
```
## Technical Spec
- Language: {{programming_language}}
- GraphQL framework: {{graphql_framework}} (Apollo, Strawberry, gqlgen, Absinthe)
- Database: {{database}}
- Auth: {{auth_strategy}}
## Deliverables
1. **Schema Design** - Complete GraphQL SDL with:
- Types (objects, inputs, enums, interfaces, unions)
- Queries with filtering, pagination, sorting
- Mutations with input validation
- Subscriptions for real-time updates
- Custom scalars (DateTime, JSON, Email, UUID)
- Introspection-friendly descriptions
2. **Resolvers** - Complete resolver implementation:
- Query resolvers with DataLoader batching
- Mutation resolvers with transactions
- Subscription resolvers with pub/sub
- Field-level resolvers for computed properties
3. **DataLoader Setup** - Batching and deduplication for N+1 prevention
4. **Directive Implementation** - @auth, @rateLimit, @cacheControl, @deprecated
5. **Error Handling** - GraphQL-specific error formatting and extensions
6. **Auth Middleware** - Context building with user authentication
7. **Pagination** - Relay-style cursor pagination implementation
8. **Complexity Analysis** - Query cost analysis and depth limiting
9. **Schema Stitching/Federation** - If microservices context applies
10. **Tests** - Resolver tests with mocked data sources
Follow GraphQL best practices. Use code-first or schema-first based on {{graphql_framework}} conventions.
Ergebnisse
GraphQL API for a blog domain (authors, posts, comments) in TypeScript with Apollo Server over Postgres. DataLoader kills the N+1.
```graphql
scalar DateTime
type Post {
id: ID!
title: String!
author: Author! # resolved via DataLoader, not per-row query
comments(first: Int = 10, after: String): CommentConnection!
createdAt: DateTime!
}
type Query {
posts(filter: PostFilter, first: Int = 20, after: String): PostConnection!
}
type Mutation {
publishPost(input: PublishPostInput!): Post! @auth(role: AUTHOR)
}
type Subscription {
commentAdded(postId: ID!): Comment!
}
```
```typescript
// Batched author lookup — one query for N posts
const authorLoader = new DataLoader<string, Author>(async (ids) => {
const rows = await db.author.findMany({ where: { id: { in: [...ids] } } });
const byId = new Map(rows.map((r) => [r.id, r]));
return ids.map((id) => byId.get(id)!);
});
const resolvers = {
Post: { author: (p, _a, ctx) => ctx.loaders.author.load(p.authorId) },
Mutation: {
publishPost: (_p, { input }, ctx) =>
ctx.db.$transaction((tx) => tx.post.update({ where: { id: input.id }, data: { published: true } })),
},
};
```
**Included:** Relay-style cursor pagination, an `@auth` directive checking the JWT in context, pub/sub-backed `commentAdded` subscription, and depth-limiting (max 7) to block abusive nested queries. Resolver tests mock the data sources.
Modell: Claude Sonnet 4
23 Likes6 SavesScore: 11
1 Kommentar
Luca Brunner·
I was skeptical but the output is genuinely production-grade.