GraphQL in Production · GraphQL Fundamentals for API Designers
Designing Mutations
Input types, payload types, idempotency and side effects.
Design mutations as specific, intention-revealing actions (cancelOrder, addCartItem) rather than generic updateOrder with every field. Use a single input object argument and return a payload type containing the changed object(s) plus any user-facing errors, so clients can update caches. Mutations at the top level run serially; make them idempotent where possible (client mutation IDs or idempotency keys passed via input or HTTP header).
Mutation styles
| Criterion | Specific mutations (cancelOrder) | Generic CRUD (updateOrder) |
|---|---|---|
| Intent & auditing | Clear | Ambiguous |
| Authorization | Per action | Per field combination (complex) |
| Validation | Focused | Many combinations |
| Evolution | Add new mutations | Input type grows endlessly |
input CancelOrderInput { orderId: ID! reason: String idempotencyKey: String }
type CancelOrderPayload {
order: Order # updated object for cache updates
userErrors: [UserError!]! # expected business errors
}
type UserError { field: [String!] code: UserErrorCode! message: String! }
enum UserErrorCode { NOT_FOUND ALREADY_SHIPPED NOT_ALLOWED }
type Mutation { cancelOrder(input: CancelOrderInput!): CancelOrderPayload! }
Common pitfalls
- Mutations returning only Boolean (clients can't update caches).
- Huge generic update mutations.
- Non-idempotent mutations retried by clients/SDKs.
Key points
- One input object, one payload type
- Intention-revealing names
- Return changed objects + userErrors
Further reading: GraphQL: Mutations
Practice questions
Why return the updated object in a mutation payload?
Answer
Normalized client caches can update every view showing that object without refetching.
How can you make a GraphQL mutation safe to retry?
Answer
Accept an idempotency key (in the input or an HTTP header), store the result per key, and return the stored payload on retries.
Open in the app to mark lessons complete, take notes and track your progress.