Menangani payload mutation
Field mutation dapat dikonfigurasi untuk mengembalikan salah satu dari 2 tipe entitas yang berbeda:
- Tipe objek payload
- Langsung entitas yang dimutasi
Tipe objek payload
Tipe objek payload berisi semua data yang berkaitan dengan mutation:
- Status mutation (sukses atau gagal)
- Error (jika ada) menggunakan tipe GraphQL yang berbeda, atau
- Entitas yang berhasil dimutasi
Misalnya, mutation updatePost mengembalikan objek bertipe PostUpdateMutationPayload, dan kita masih perlu melakukan query pada field post-nya untuk mengambil entitas post yang telah diperbarui:
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
}
}
}Objek payload memungkinkan kita merepresentasikan error dengan lebih baik, bahkan dengan memiliki tipe GraphQL unik untuk setiap jenis error. Ini memungkinkan kita menampilkan respons yang berbeda untuk error yang berbeda dalam aplikasi, sehingga meningkatkan pengalaman pengguna.
Pada contoh di atas, jika operasi berhasil, kita akan menerima:
{
"data": {
"updatePost": {
"status": "SUCCESS",
"errors": null,
"post": {
"id": 1724,
"title": "Some title",
"status": "publish"
}
}
}
}Jika pengguna belum masuk, kita akan menerima:
{
"data": {
"updatePost": {
"status": "FAILURE",
"errors": [
{
"__typename": "UserIsNotLoggedInErrorPayload",
"message": "You must be logged in to create or update custom posts"
}
],
"post": null
}
}
}Jika pengguna tidak memiliki izin untuk mengedit post, kita akan menerima:
{
"data": {
"updatePost": {
"status": "FAILURE",
"errors": [
{
"__typename": "LoggedInUserHasNoEditingCustomPostCapabilityErrorPayload",
"message": "Your user doesn't have permission for editing custom posts."
}
],
"post": null
}
}
}Dalam mode ini, skema GraphQL akan berisi banyak tipe tambahan MutationPayload, MutationErrorPayloadUnion, dan ErrorPayload, sehingga ukurannya akan lebih besar:

Query objek payload mutation
Setiap mutation dalam skema memiliki field yang sesuai untuk melakukan query pada objek payload yang baru dibuat, dengan nama {mutationName}MutationPayloadObjects.
Field-field ini meliputi:
addCommentToCustomPostMutationPayloadObjects(untukaddCommentToCustomPost)createCustomPostMutationPayloadObjects(untukcreateCustomPost)createMediaItemMutationPayloadObjects(untukcreateMediaItem)createPageMutationPayloadObjects(untukcreatePage)createPostMutationPayloadObjects(untukcreatePost)removeFeaturedImageFromCustomPostMutationPayloadObjects(untukremoveFeaturedImageFromCustomPost)replyCommentMutationPayloadObjects(untukreplyComment)setCategoriesOnPostMutationPayloadObjects(untuksetCategoriesOnPost)setFeaturedImageOnCustomPostMutationPayloadObjects(untuksetFeaturedImageOnCustomPost)setTagsOnPostMutationPayloadObjects(untuksetTagsOnPost)updateCustomPostMutationPayloadObjects(untukupdateCustomPost)updatePageMutationPayloadObjects(untukupdatePage)updatePostMutationPayloadObjects(untukupdatePost)
Field-field ini memungkinkan kita mengambil hasil mutation yang dieksekusi menggunakan @applyField saat mengiterasi item dalam sebuah array.
Misalnya, query berikut menduplikasi post secara massal:
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
}
}
}Secara default, field-field ini tidak ditambahkan ke skema GraphQL. Untuk itu, kita harus memilih opsi "Use payload types for mutations, and add fields to query those payload objects".
Entitas yang dimutasi
Mutation akan langsung mengembalikan entitas yang dimutasi jika berhasil, atau null jika gagal, dan pesan error apa pun akan ditampilkan di entri errors tingkat atas pada respons JSON.
Misalnya, mutation updatePost akan mengembalikan objek bertipe Post:
mutation UpdatePost {
updatePost(input: {
id: 1724,
title: "New title",
status: publish
}) {
id
title
status
}
}Jika operasi berhasil, kita akan menerima:
{
"data": {
"updatePost": {
"id": 1724,
"title": "Some title",
"status": "publish"
}
}
}Jika terjadi error, error tersebut akan muncul di bawah entri errors pada respons. Misalnya, jika pengguna belum masuk, kita akan menerima:
{
"errors": [
{
"message": "You must be logged in to create or update custom posts'",
"locations": [
{
"line": 2,
"column": 3
}
]
}
],
"data": {
"updatePost": null
}
}Kita perlu memperhatikan bahwa, akibatnya, entri errors tingkat atas akan berisi tidak hanya error sintaksis, validasi skema, dan logika (misalnya: tidak meneruskan nama argumen field, meminta field yang tidak ada, atau memanggil _sendHTTPRequest saat jaringan mati), tetapi juga error "validasi konten" (misalnya: "Anda tidak diizinkan untuk memodifikasi post ini").
Karena tidak ada tipe tambahan yang ditambahkan, skema GraphQL akan terlihat lebih ramping:

Menangani tipe objek payload untuk mutation
Mari kita lihat cara menangani opsi pertama, yaitu tipe objek payload.
Mutation dalam skema mengembalikan beberapa objek payload, yang menyediakan error (jika ada) yang dihasilkan dari mutation, atau objek yang dimodifikasi jika berhasil (2 properti ini kemungkinan besar bersifat eksklusif: baik errors atau object yang akan memiliki nilai, dan yang lainnya akan null).
Error disediakan melalui beberapa tipe "ErrorPayloadUnion", yang berisi semua kemungkinan error untuk mutation tersebut. Setiap kemungkinan error adalah beberapa tipe "ErrorPayload" yang mengimplementasikan interface ErrorPayload.
Misalnya, operasi updatePost mengembalikan PostUpdateMutationPayload, yang berisi field-field berikut:
status: apakah operasi berhasil atau tidak, dengan nilaiSUCCESSatauFAILUREpostdanpostID: objek post yang diperbarui dan ID-nya, jika pembaruan berhasilerrors: daftarCustomPostUpdateMutationErrorPayloadUnion, jika pembaruan gagal.
Tipe union CustomPostUpdateMutationErrorPayloadUnion berisi daftar semua kemungkinan error yang dapat terjadi saat memodifikasi custom post:
CustomPostDoesNotExistErrorPayloadGenericErrorPayloadLoggedInUserHasNoEditingCustomPostCapabilityErrorPayloadLoggedInUserHasNoPermissionToEditCustomPostErrorPayloadLoggedInUserHasNoPublishingCustomPostCapabilityErrorPayloadUserIsNotLoggedInErrorPayload
Tipe error GenericErrorPayload terdapat dalam semua tipe "ErrorPayloadUnion". Tipe ini digunakan setiap kali alasan spesifik untuk error tidak dapat ditunjukkan, seperti ketika wp_update_post hanya menghasilkan WP_Error. Tipe ini menyediakan dua field tambahan: code dan data.
Kemudian, untuk mengeksekusi mutation updatePost, kita dapat menjalankan:
mutation UpdatePost(
$postId: ID!
$title: String!
) {
updatePost(
input: {
id: $postId,
title: $title,
}
) {
status
errors {
__typename
...on ErrorPayload {
message
}
...on GenericErrorPayload {
code
}
}
post {
id
title
}
}
}Jika operasi berhasil, kita akan menerima:
{
"data": {
"updatePost": {
"status": "SUCCESS",
"errors": null,
"post": {
"id": 1724,
"title": "This incredible title"
}
}
}
}Jika pengguna belum masuk, kita akan menerima:
{
"data": {
"updatePost": {
"status": "FAILURE",
"errors": [
{
"__typename": "UserIsNotLoggedInErrorPayload",
"message": "You must be logged in to create or update custom posts"
}
],
"post": null
}
}
}Jika pengguna tidak memiliki izin untuk mengedit post, kita akan menerima:
{
"data": {
"updatePost": {
"status": "FAILURE",
"errors": [
{
"__typename": "LoggedInUserHasNoEditingCustomPostCapabilityErrorPayload",
"message": "Your user doesn't have permission for editing custom posts."
}
],
"post": null
}
}
}