Implementing Batch Operations
1. Creating Batch Mutations
Example: Batch create
type Mutation {
createPosts(inputs: [CreatePostInput!]!): CreatePostsPayload!
}
type CreatePostsPayload {
posts: [Post!]!
errors: [BatchError!]!
}
type BatchError { index: Int!, message: String!, code: String! }
2. Using Input Lists
| Pattern | Detail |
|---|---|
| List of input objects | inputs: [CreateXInput!]! |
| Bounded | Max 100 per batch (configurable) |
| Order-preserving | Index in result matches input index |
3. Returning Batch Results
| Field | Detail |
|---|---|
| results: [Result!]! | One per input, in order |
| errors | Indexed errors |
| summary | Counts: success, failed, total |
4. Handling Partial Failures
| Strategy | When |
|---|---|
| All-or-nothing (transaction) | Strong consistency required |
| Best-effort (independent) | Each input independent (e.g., notifications) |
| Result union per item | Per-item Success | Error |
5. Validating Batch Size
Example: Cap batch input
if (inputs.length > 100) {
throw new GraphQLError("Batch too large (max 100)", { extensions: { code: "BAD_USER_INPUT" } });
}
6. Implementing Transactional Batches
Example: DB transaction
return db.$transaction(async (tx) => {
const posts = [];
for (const input of inputs) {
posts.push(await tx.post.create({ data: input }));
}
return { posts, errors: [] };
});
7. Optimizing Batch Performance
| Technique | Detail |
|---|---|
| createMany | Single INSERT for the batch |
| Bulk validate first | Fail fast before any write |
| Parallelize independent items | Promise.all with concurrency limit |
8. Using Batch Loaders
| Use | Detail |
|---|---|
| DataLoader inside resolver | Batch lookups while building results |
| Prime after batch | Cache the newly-created entities |
9. Implementing Batch Queries
Example: Batch get
type Query {
usersByIds(ids: [ID!]!): [User]! # null for missing, preserves order
}
10. Returning Batch Metadata
| Field | Detail |
|---|---|
| processedCount | Total processed |
| successCount | Successful |
| failedCount | Failed (with errors) |
| durationMs | Server-side wall time |