Handling mutation payloads
Mutation fields can be configured to return either of these 2 different entity types:
- A payload object type
- Directly the mutated entity
Payload object type
A payload object type contains all the data concerning the mutation:
- The status of the mutation (success or failure)
- The errors (if any) using distinctive GraphQL types, or
- The successfully mutated entity
For instance, mutation updatePost
returns an object of type PostUpdateMutationPayload
, and we still need to query its field post
to retrieve the updated post entity:
The payload object allows us to represent better the errors, even having a unique GraphQL type per kind of error. This allows us to present different reactions for different errors in the application, thus improving the user experience.
In the example above, if the operation was successful, we will receive:
If the user is not logged in, we will receive:
If the user doesn't have the permission to edit posts, we will receive:
In this mode, the GraphQL schema will contain plenty of additional MutationPayload
, MutationErrorPayloadUnion
and ErrorPayload
types, so it will have a bigger size:
Query the mutation payload objects
Every mutation in the schema has a corresponding field to query its recently-created payload objects, with name {mutationName}MutationPayloadObjects
.
These fields include:
addCommentToCustomPostMutationPayloadObjects
(foraddCommentToCustomPost
)createCustomPostMutationPayloadObjects
(forcreateCustomPost
)createMediaItemMutationPayloadObjects
(forcreateMediaItem
)createPageMutationPayloadObjects
(forcreatePage
)createPostMutationPayloadObjects
(forcreatePost
)removeFeaturedImageFromCustomPostMutationPayloadObjects
(forremoveFeaturedImageFromCustomPost
)replyCommentMutationPayloadObjects
(forreplyComment
)setCategoriesOnPostMutationPayloadObjects
(forsetCategoriesOnPost
)setFeaturedImageOnCustomPostMutationPayloadObjects
(forsetFeaturedImageOnCustomPost
)setTagsOnPostMutationPayloadObjects
(forsetTagsOnPost
)updateCustomPostMutationPayloadObjects
(forupdateCustomPost
)updatePageMutationPayloadObjects
(forupdatePage
)updatePostMutationPayloadObjects
(forupdatePost
)
These fields enable us to retrieve the results of mutations executed using @applyField
while iterating the items in an array.
For instance, the following query duplicates posts in bulk:
By default, these fields are not added to the GraphQL schema. For that, we must select option "Use payload types for mutations, and add fields to query those payload objects".
Mutated entity
The mutation will directly return the mutated entity in case of success, or null
in case of failure, and any error message will be displayed in the JSON response's top-level errors
entry.
For instance, mutation updatePost
will return the object of type Post
:
If the operation was successful, we will receive:
In case of errors, these will appear under the errors
entry of the response. For instance, if the user is not logged in, we will receive:
We must notice that, as a result, the top-level errors
entry will contain not only syntax, schema validation and logic errors (eg: not passing a field argument's name, requesting a non-existing field, or calling _sendHTTPRequest
and the network is down respectively), but also "content validation" errors (eg: "you're not authorized to modify this post").
Because there are no additional types added, the GraphQL schema will look leaner:
Handling the payload object type for mutations
Let's see how to handle the first option, the payload object type.
Mutations in the schema return some payload object, which provides any error(s) resulting from the mutation, or the modified object if successful (these 2 properties are most likely exclusive: either errors
or object
will have a value, and the other one will be null
).
Errors are provided via some "ErrorPayloadUnion" type, containing all possible errors for that mutation. Every possible error is some "ErrorPayload" type that implements the interface ErrorPayload
.
For instance, the operation updatePost
returns a PostUpdateMutationPayload
, which contains the following fields:
status
: whether the operation was successful or not, with either valueSUCCESS
orFAILURE
post
andpostID
: the updated post object and its ID, if the update was successfulerrors
: a list ofCustomPostUpdateMutationErrorPayloadUnion
, if the update failed.
The union type CustomPostUpdateMutationErrorPayloadUnion
contains the list of all possible errors that can happen when modifying a custom post:
CustomPostDoesNotExistErrorPayload
GenericErrorPayload
LoggedInUserHasNoEditingCustomPostCapabilityErrorPayload
LoggedInUserHasNoPermissionToEditCustomPostErrorPayload
LoggedInUserHasNoPublishingCustomPostCapabilityErrorPayload
UserIsNotLoggedInErrorPayload
Error type GenericErrorPayload
is contained by all "ErrorPayloadUnion" types. It is used whenever the specific reason for the error cannot be pointed out, such as when wp_update_post
simply produces WP_Error
. This type provides two additional fields: code
and data
.
Then, to execute the updatePost
mutation, we can execute:
If the operation was successful, we will receive:
If the user is not logged in, we will receive:
If the user doesn't have the permission to edit posts, we will receive: