Mutation Response Design
Mutation responses should be designed intentionally rather than simply returning an arbitrary object.
A simple mutation can return the changed resource:
createPost(input: CreatePostInput!): Post!
For more complex operations, a payload type can be useful:
type CreatePostPayload {
post: Post
errors: [UserError!]!
success: Boolean!
}
type UserError {
field: String
message: String!
code: String
}
The mutation becomes:
createPost(input: CreatePostInput!): CreatePostPayload!
This design gives the client a structured place for operation-specific metadata.
However, payload types should not become a generic dumping ground for every possible server state. Keep them meaningful to the operation.
Another important design decision is whether expected business failures should be represented as normal structured data, GraphQL errors, or both. A consistent application-wide error strategy is more important than blindly choosing one pattern.
For example, invalid credentials might be an expected authentication failure, while an unexpected database outage is an exceptional server failure. Treating both identically can make client behavior and observability harder.
createPost → PostcreatePost → CreatePostPayloadfield + message + code- Mutation response design should match operation complexity.
- Payload types can provide structured operation results.
- Expected business errors and unexpected system failures should be distinguished.
- A consistent error strategy improves client and server behavior.
When is a mutation payload type particularly useful?