Mutation-Payloads verarbeiten
Mutation-Felder können so konfiguriert werden, dass sie einen dieser 2 verschiedenen Entitätstypen zurückgeben:
- Einen Payload-Objekttyp
- Direkt die geänderte Entität
Payload-Objekttyp
Ein Payload-Objekttyp enthält alle Daten zur Mutation:
- Den Status der Mutation (Erfolg oder Fehler)
- Die Fehler (falls vorhanden) mithilfe eindeutiger GraphQL-Typen, oder
- Die erfolgreich geänderte Entität
Zum Beispiel gibt die Mutation updatePost ein Objekt vom Typ PostUpdateMutationPayload zurück, und wir müssen noch dessen Feld post abfragen, um die aktualisierte Post-Entität zu erhalten:
mutation UpdatePost {
updatePost(input: {
id: 1724,
title: "New title",
status: publish
}) {
# This is the status of the mutation: SUCCESS or FAILURE
status
errors {
__typename
...on ErrorPayload {
message
}
}
post {
id
title
# This is the status of the post: publish, pending, trash, etc
status
}
}
}Das Payload-Objekt ermöglicht es uns, Fehler besser darzustellen – sogar mit einem eindeutigen GraphQL-Typ pro Fehlerart. So können wir in der Anwendung auf unterschiedliche Fehler verschieden reagieren und damit die Benutzererfahrung verbessern.
Im obigen Beispiel erhalten wir bei erfolgreichem Vorgang:
{
"data": {
"updatePost": {
"status": "SUCCESS",
"errors": null,
"post": {
"id": 1724,
"title": "Some title",
"status": "publish"
}
}
}
}Wenn der Benutzer nicht eingeloggt ist, erhalten wir:
{
"data": {
"updatePost": {
"status": "FAILURE",
"errors": [
{
"__typename": "UserIsNotLoggedInErrorPayload",
"message": "You must be logged in to create or update custom posts"
}
],
"post": null
}
}
}Wenn der Benutzer keine Berechtigung zum Bearbeiten von Posts hat, erhalten wir:
{
"data": {
"updatePost": {
"status": "FAILURE",
"errors": [
{
"__typename": "LoggedInUserHasNoEditingCustomPostCapabilityErrorPayload",
"message": "Your user doesn't have permission for editing custom posts."
}
],
"post": null
}
}
}In diesem Modus enthält das GraphQL-Schema zahlreiche zusätzliche Typen MutationPayload, MutationErrorPayloadUnion und ErrorPayload, weshalb es größer ausfällt:

Mutation-Payload-Objekte abfragen
Jede Mutation im Schema verfügt über ein entsprechendes Feld, um die zuletzt erstellten Payload-Objekte abzufragen, mit dem Namen {mutationName}MutationPayloadObjects.
Diese Felder umfassen:
addCommentToCustomPostMutationPayloadObjects(füraddCommentToCustomPost)createCustomPostMutationPayloadObjects(fürcreateCustomPost)createMediaItemMutationPayloadObjects(fürcreateMediaItem)createPageMutationPayloadObjects(fürcreatePage)createPostMutationPayloadObjects(fürcreatePost)removeFeaturedImageFromCustomPostMutationPayloadObjects(fürremoveFeaturedImageFromCustomPost)replyCommentMutationPayloadObjects(fürreplyComment)setCategoriesOnPostMutationPayloadObjects(fürsetCategoriesOnPost)setFeaturedImageOnCustomPostMutationPayloadObjects(fürsetFeaturedImageOnCustomPost)setTagsOnPostMutationPayloadObjects(fürsetTagsOnPost)updateCustomPostMutationPayloadObjects(fürupdateCustomPost)updatePageMutationPayloadObjects(fürupdatePage)updatePostMutationPayloadObjects(fürupdatePost)
Diese Felder ermöglichen es uns, die Ergebnisse von Mutations abzurufen, die mit @applyField beim Iterieren über Array-Elemente ausgeführt wurden.
Die folgende Query dupliziert beispielsweise Posts in einem Durchgang:
query GetPostsAndExportData
{
postsToDuplicate: posts {
title
rawContent
excerpt
# Already create (and export) the inputs for the mutation
postInput: _echo(value: {
title: $__title
contentAs: {
html: $__rawContent
},
excerpt: $__excerpt
})
@export(as: "postInput", type: LIST)
@remove
}
}
mutation CreatePosts
@depends(on: "GetPostsAndExportData")
{
createdPostMutationPayloadObjectIDs: _echo(value: $postInput)
@underEachArrayItem(
passValueOnwardsAs: "input"
)
@applyField(
name: "createPost"
arguments: {
input: $input
},
setResultInResponse: true
)
@export(as: "createdPostMutationPayloadObjectIDs")
}
query DuplicatePosts
@depends(on: "CreatePosts")
{
createdPostMutationObjectPayloads: createPostMutationPayloadObjects(input: {
ids: $createdPostMutationPayloadObjectIDs
}) {
status
errors {
__typename
...on ErrorPayload {
message
}
}
post {
id
title
rawContent
excerpt
}
}
}Standardmäßig werden diese Felder nicht zum GraphQL-Schema hinzugefügt. Dazu müssen wir die Option "Use payload types for mutations, and add fields to query those payload objects" auswählen.
Geänderte Entität
Die Mutation gibt bei Erfolg direkt die geänderte Entität zurück, oder null bei einem Fehler, und Fehlermeldungen erscheinen im obersten errors-Eintrag der JSON-Antwort.
Zum Beispiel gibt die Mutation updatePost das Objekt vom Typ Post zurück:
mutation UpdatePost {
updatePost(input: {
id: 1724,
title: "New title",
status: publish
}) {
id
title
status
}
}Bei erfolgreichem Vorgang erhalten wir:
{
"data": {
"updatePost": {
"id": 1724,
"title": "Some title",
"status": "publish"
}
}
}Bei Fehlern erscheinen diese unter dem errors-Eintrag der Antwort. Wenn der Benutzer beispielsweise nicht eingeloggt ist, erhalten wir:
{
"errors": [
{
"message": "You must be logged in to create or update custom posts'",
"locations": [
{
"line": 2,
"column": 3
}
]
}
],
"data": {
"updatePost": null
}
}Wir müssen beachten, dass der oberste errors-Eintrag dadurch nicht nur Syntax-, Schema-Validierungs- und Logikfehler enthält (z.B.: keinen Feldargumentnamen übergeben, ein nicht vorhandenes Feld anfordern oder _sendHTTPRequest aufrufen, während das Netzwerk nicht verfügbar ist), sondern auch "Inhaltsvalidierungsfehler" (z.B.: "Du bist nicht berechtigt, diesen Post zu ändern").
Da keine zusätzlichen Typen hinzugefügt werden, wirkt das GraphQL-Schema schlanker:

Den Payload-Objekttyp für Mutations verarbeiten
Schauen wir uns an, wie wir die erste Option, den Payload-Objekttyp, verarbeiten.
Mutations im Schema geben ein Payload-Objekt zurück, das alle aus der Mutation resultierenden Fehler oder – bei Erfolg – das geänderte Objekt enthält (diese 2 Eigenschaften schließen sich höchstwahrscheinlich gegenseitig aus: entweder errors oder object hat einen Wert, und die andere ist null).
Fehler werden über einen "ErrorPayloadUnion"-Typ bereitgestellt, der alle möglichen Fehler für diese Mutation enthält. Jeder mögliche Fehler ist ein "ErrorPayload"-Typ, der das Interface ErrorPayload implementiert.
Zum Beispiel gibt die Operation updatePost ein PostUpdateMutationPayload zurück, das folgende Felder enthält:
status: ob die Operation erfolgreich war oder nicht, mit dem WertSUCCESSoderFAILUREpostundpostID: das aktualisierte Post-Objekt und seine ID, wenn die Aktualisierung erfolgreich warerrors: eine Liste vonCustomPostUpdateMutationErrorPayloadUnion, wenn die Aktualisierung fehlgeschlagen ist.
Der Union-Typ CustomPostUpdateMutationErrorPayloadUnion enthält die Liste aller möglichen Fehler, die beim Ändern eines Custom Posts auftreten können:
CustomPostDoesNotExistErrorPayloadGenericErrorPayloadLoggedInUserHasNoEditingCustomPostCapabilityErrorPayloadLoggedInUserHasNoPermissionToEditCustomPostErrorPayloadLoggedInUserHasNoPublishingCustomPostCapabilityErrorPayloadUserIsNotLoggedInErrorPayload
Der Fehlertyp GenericErrorPayload ist in allen "ErrorPayloadUnion"-Typen enthalten. Er wird verwendet, wenn der spezifische Grund für den Fehler nicht ermittelt werden kann, z.B. wenn wp_update_post einfach WP_Error erzeugt. Dieser Typ stellt zwei zusätzliche Felder bereit: code und data.
Um die Mutation updatePost auszuführen, können wir Folgendes ausführen:
mutation UpdatePost(
$postId: ID!
$title: String!
) {
updatePost(
input: {
id: $postId,
title: $title,
}
) {
status
errors {
__typename
...on ErrorPayload {
message
}
...on GenericErrorPayload {
code
}
}
post {
id
title
}
}
}Bei erfolgreichem Vorgang erhalten wir:
{
"data": {
"updatePost": {
"status": "SUCCESS",
"errors": null,
"post": {
"id": 1724,
"title": "This incredible title"
}
}
}
}Wenn der Benutzer nicht eingeloggt ist, erhalten wir:
{
"data": {
"updatePost": {
"status": "FAILURE",
"errors": [
{
"__typename": "UserIsNotLoggedInErrorPayload",
"message": "You must be logged in to create or update custom posts"
}
],
"post": null
}
}
}Wenn der Benutzer keine Berechtigung zum Bearbeiten von Posts hat, erhalten wir:
{
"data": {
"updatePost": {
"status": "FAILURE",
"errors": [
{
"__typename": "LoggedInUserHasNoEditingCustomPostCapabilityErrorPayload",
"message": "Your user doesn't have permission for editing custom posts."
}
],
"post": null
}
}
}