GraphQL API ile Etkileşim
GraphQL API ile EtkileşimMutation Payload Yönetimi

Mutation Payload Yönetimi

Mutation alanları, şu 2 farklı varlık türünden birini döndürecek şekilde yapılandırılabilir:

  • Bir payload nesne türü
  • Doğrudan değiştirilen varlık

Payload nesne türü

Bir payload nesne türü, mutation ile ilgili tüm verileri içerir:

  • Mutation'ın durumu (başarı veya başarısızlık)
  • Hatalar (varsa) ayırt edici GraphQL türleri kullanılarak, ya da
  • Başarıyla değiştirilen varlık

Örneğin, updatePost mutation'ı PostUpdateMutationPayload türünde bir nesne döndürür ve güncellenen gönderi varlığını almak için hâlâ post alanını sorgulamak gerekir:

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
    }
  }
}

Payload nesnesi, hataları daha iyi temsil etmemizi sağlar; her hata türü için benzersiz bir GraphQL türü bile bulunur. Bu sayede uygulamada farklı hatalar için farklı tepkiler sunabilir ve kullanıcı deneyimini iyileştirebiliriz.

Yukarıdaki örnekte, işlem başarılı olursa şunu alırız:

{
  "data": {
    "updatePost": {
      "status": "SUCCESS",
      "errors": null,
      "post": {
        "id": 1724,
        "title": "Some title",
        "status": "publish"
      }
    }
  }
}

Kullanıcı oturum açmamışsa şunu alırız:

{
  "data": {
    "updatePost": {
      "status": "FAILURE",
      "errors": [
        {
          "__typename": "UserIsNotLoggedInErrorPayload",
          "message": "You must be logged in to create or update custom posts"
        }
      ],
      "post": null
    }
  }
}

Kullanıcının gönderileri düzenleme izni yoksa şunu alırız:

{
  "data": {
    "updatePost": {
      "status": "FAILURE",
      "errors": [
        {
          "__typename": "LoggedInUserHasNoEditingCustomPostCapabilityErrorPayload",
          "message": "Your user doesn't have permission for editing custom posts."
        }
      ],
      "post": null
    }
  }
}

Bu modda, GraphQL şeması çok sayıda ek MutationPayload, MutationErrorPayloadUnion ve ErrorPayload türü içereceğinden daha büyük bir boyuta sahip olacaktır:

Mutations için payload nesne türlerine sahip GraphQL şeması

Mutation payload nesnelerini sorgulamak

Şemadaki her mutation'ın, yakın zamanda oluşturulan payload nesnelerini sorgulamak için {mutationName}MutationPayloadObjects adında karşılık gelen bir alanı vardır.

Bu alanlar şunları içerir:

  • addCommentToCustomPostMutationPayloadObjects (addCommentToCustomPost için)
  • createCustomPostMutationPayloadObjects (createCustomPost için)
  • createMediaItemMutationPayloadObjects (createMediaItem için)
  • createPageMutationPayloadObjects (createPage için)
  • createPostMutationPayloadObjects (createPost için)
  • removeFeaturedImageFromCustomPostMutationPayloadObjects (removeFeaturedImageFromCustomPost için)
  • replyCommentMutationPayloadObjects (replyComment için)
  • setCategoriesOnPostMutationPayloadObjects (setCategoriesOnPost için)
  • setFeaturedImageOnCustomPostMutationPayloadObjects (setFeaturedImageOnCustomPost için)
  • setTagsOnPostMutationPayloadObjects (setTagsOnPost için)
  • updateCustomPostMutationPayloadObjects (updateCustomPost için)
  • updatePageMutationPayloadObjects (updatePage için)
  • updatePostMutationPayloadObjects (updatePost için)

Bu alanlar, bir dizideki öğeler üzerinde yineleme yaparken @applyField ile çalıştırılan mutations'ların sonuçlarını almamızı sağlar.

Örneğin, aşağıdaki query gönderileri toplu olarak çoğaltır:

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
    }
  }
}

Varsayılan olarak, bu alanlar GraphQL şemasına eklenmez. Bunun için "Use payload types for mutations, and add fields to query those payload objects" seçeneğini seçmemiz gerekir.

Değiştirilen varlık

Mutation, başarı durumunda doğrudan değiştirilen varlığı, başarısızlık durumunda ise null değerini döndürür; hata mesajları JSON yanıtının üst düzey errors girişinde gösterilir.

Örneğin, updatePost mutation'ı Post türünde nesneyi döndürür:

mutation UpdatePost {
  updatePost(input: {
    id: 1724,
    title: "New title",
    status: publish
  }) {
    id
    title
    status
  }
}

İşlem başarılı olursa şunu alırız:

{
  "data": {
    "updatePost": {
      "id": 1724,
      "title": "Some title",
      "status": "publish"
    }
  }
}

Hata durumunda, hatalar yanıtın errors girişi altında görünür. Örneğin, kullanıcı oturum açmamışsa şunu alırız:

{
    "errors": [
      {
        "message": "You must be logged in to create or update custom posts'",
        "locations": [
          {
            "line": 2,
            "column": 3
          }
        ]
      }
  ],
  "data": {
    "updatePost": null
  }
}

Sonuç olarak, üst düzey errors girişinin yalnızca sözdizimi, şema doğrulama ve mantık hatalarını (örn.: bir alan argümanının adını geçmemek, var olmayan bir alan istemek ya da _sendHTTPRequest çağrısı yapmak ve ağın çevrimdışı olması) değil, aynı zamanda "içerik doğrulama" hatalarını da (örn.: "bu gönderiyi değiştirme yetkiniz yok") içereceğini unutmayın.

Ek tür eklenmediğinden, GraphQL şeması daha sade görünür:

Mutations için payload nesne türleri olmayan GraphQL şeması

Mutations için payload nesne türünü yönetmek

Birinci seçeneği, yani payload nesne türünü nasıl ele alacağımıza bakalım.

Şemadaki mutations, mutation'dan kaynaklanan hataları ya da başarılı olduğunda değiştirilen nesneyi sağlayan bir payload nesnesi döndürür (bu 2 özellik büyük olasılıkla birbirini dışlar: ya errors ya da object bir değere sahip olacak, diğeri null olacaktır).

Hatalar, o mutation için tüm olası hataları içeren bir "ErrorPayloadUnion" türü aracılığıyla sağlanır. Her olası hata, ErrorPayload arayüzünü uygulayan bir "ErrorPayload" türüdür.

Örneğin, updatePost işlemi şu alanları içeren PostUpdateMutationPayload döndürür:

  • status: işlemin başarılı olup olmadığı; SUCCESS veya FAILURE değerlerinden birini alır
  • post ve postID: güncelleme başarılıysa güncellenen gönderi nesnesi ve kimliği
  • errors: güncelleme başarısız olursa CustomPostUpdateMutationErrorPayloadUnion listesi.

CustomPostUpdateMutationErrorPayloadUnion union türü, bir custom post değiştirilirken oluşabilecek tüm olası hataların listesini içerir:

  • CustomPostDoesNotExistErrorPayload
  • GenericErrorPayload
  • LoggedInUserHasNoEditingCustomPostCapabilityErrorPayload
  • LoggedInUserHasNoPermissionToEditCustomPostErrorPayload
  • LoggedInUserHasNoPublishingCustomPostCapabilityErrorPayload
  • UserIsNotLoggedInErrorPayload

GenericErrorPayload hata türü, tüm "ErrorPayloadUnion" türleri tarafından içerilir. wp_update_post'un yalnızca WP_Error üretmesi gibi hatanın özel nedeninin belirlenemediği durumlarda kullanılır. Bu tür iki ek alan sağlar: code ve data.

updatePost mutation'ını çalıştırmak için şunu çalıştırabiliriz:

mutation UpdatePost(
  $postId: ID!
  $title: String!
) {
  updatePost(
    input: {
      id: $postId,
      title: $title,
    }
  ) {
    status
    errors {
      __typename
      ...on ErrorPayload {
        message
      }
      ...on GenericErrorPayload {
        code
      }
    }
    post {
      id
      title
    }
  }
}

İşlem başarılı olursa şunu alırız:

{
  "data": {
    "updatePost": {
      "status": "SUCCESS",
      "errors": null,
      "post": {
        "id": 1724,
        "title": "This incredible title"
      }
    }
  }
}

Kullanıcı oturum açmamışsa şunu alırız:

{
  "data": {
    "updatePost": {
      "status": "FAILURE",
      "errors": [
        {
          "__typename": "UserIsNotLoggedInErrorPayload",
          "message": "You must be logged in to create or update custom posts"
        }
      ],
      "post": null
    }
  }
}

Kullanıcının gönderileri düzenleme izni yoksa şunu alırız:

{
  "data": {
    "updatePost": {
      "status": "FAILURE",
      "errors": [
        {
          "__typename": "LoggedInUserHasNoEditingCustomPostCapabilityErrorPayload",
          "message": "Your user doesn't have permission for editing custom posts."
        }
      ],
      "post": null
    }
  }
}