บทช่วยสอน Schema
บทช่วยสอน Schemaบทเรียนที่ 7: การปรับเนื้อหาแบบกลุ่ม

บทเรียนที่ 7: การปรับเนื้อหาแบบกลุ่ม

บทเรียนนี้ปรับเนื้อหาแบบกลุ่ม โดยอัปเดต title, content และ excerpt ของหลายโพสต์ด้วย GraphQL request เพียงครั้งเดียว

เพื่อให้ GraphQL query นี้ทำงานได้ Schema Configuration ที่ใช้กับ endpoint จะต้องเปิดใช้งาน Nested Mutations

GraphQL query ด้านล่างนี้จะดึงข้อมูลของหลายโพสต์ ทำการค้นหาและแทนที่ในฟิลด์ title, content และ excerpt ของแต่ละโพสต์ ปรับค่าเหล่านี้ให้เป็น input สำหรับ mutation และ export ตัวแปรไดนามิกตัวเดียว $postInputs ที่มีผลลัพธ์ทั้งหมดในรูปแบบ dictionary โดยมีรูปแบบดังนี้:

{
  "${post ID}": {
    "title": "${adapted post title}",
    "excerpt": "${adapted post excerpt}"
  },
  // repeat for all other posts ...
}

ในการดำเนินการ mutation แต่ละรายการเหล่านี้จะถูกดึงผ่าน _objectProperty (โดยใช้ ${post ID} เป็นคีย์) และส่งต่อเป็น input เพื่ออัปเดตโพสต์:

query TransformAndExportData(
  $limit: Int! = 5,
  $offset: Int! = 0,
  $replaceFrom: [String!]!
  $replaceTo: [String!]!
) {
  posts: posts(
    pagination: { limit: $limit, offset: $offset }
    sort: { by: ID, order: ASC }
  ) {
    rawTitle
    rawContent
    rawExcerpt
      @strReplaceMultiple(
        search: $replaceFrom
        replaceWith: $replaceTo
        affectAdditionalFieldsUnderPos: [1, 2]
      )
      @deferredExport(
        as: "postAdaptedSources"
        type: DICTIONARY
        affectAdditionalFieldsUnderPos: [1, 2]
      )
  }
}
 
query AdaptDataForMutationInput
  @depends(on: "TransformAndExportData")
{
  postInputs: _echo(value: $postAdaptedSources)
    @underEachJSONObjectProperty(
      passValueOnwardsAs: "adaptedSource",
      affectDirectivesUnderPos: [1, 2, 3, 4]
    )
      @applyField(
        name: "_objectProperty",
        arguments: {
          object: $adaptedSource,
          by: {
            key: "rawTitle"
          }
        },
        passOnwardsAs: "adaptedTitle"
      )
      @applyField(
        name: "_objectProperty",
        arguments: {
          object: $adaptedSource,
          by: {
            key: "rawExcerpt"
          }
        },
        passOnwardsAs: "adaptedExcerpt"
      )
      @applyField(
        name: "_objectProperty",
        arguments: {
          object: $adaptedSource,
          by: {
            key: "rawContent"
          }
        },
        passOnwardsAs: "adaptedContent"
      )
      @applyField(
        name: "_echo",
        arguments: {
          value: {
            title: $adaptedTitle,
            excerpt: $adaptedExcerpt,
            contentAs: {
              html: $adaptedContent
            }
          }
        },
        setResultInResponse: true
      )
    @export(as: "postInputs")
}
 
mutation UpdatePost(
  $limit: Int! = 5,
  $offset: Int! = 0
)
  @depends(on: "AdaptDataForMutationInput")
{
  adaptedPosts: posts(
    pagination: { limit: $limit, offset: $offset }
    sort: { by: ID, order: ASC }
  ) {
    id
    postInput: _objectProperty(
      object: $postInputs,
      by: { key: $__id }
    ) @remove
    update(input: $__postInput) {
      status
      errors {
        __typename
        ...on ErrorPayload {
          message
        }
      }
      post {
        title
        content
        excerpt
      }
    }
  }
}
  • ส่วนขยาย Field on Field มีไดเรกทีฟ @applyField ซึ่งเมื่อเรียกใช้ร่วมกับ _objectProperty จะดึงพร็อพเพอร์ตีจากแต่ละรายการใน JSON object (ที่ส่งมาเป็น $adaptedSource) แล้วใช้ _echo สร้าง JSON input ที่สอดคล้องกันพร้อมพร็อพเพอร์ตีเหล่านั้น
  • นอกจากฟิลด์ฟังก์ชันแล้ว ส่วนขยาย PHP Functions via Schema ยังมีฟังก์ชันการทำงานผ่าน "ไดเรกทีฟฟังก์ชัน" ที่สอดคล้องกัน เช่น @strReplaceMultiple
  • เมื่อเปิดใช้งาน Multi-Field Directives เราสามารถใช้ไดเรกทีฟกับฟิลด์มากกว่าหนึ่งฟิลด์ได้ โดยระบุตำแหน่งสัมพัทธ์ของฟิลด์เพิ่มเติมผ่านอาร์กิวเมนต์ affectAdditionalFieldsUnderPos
  • เมื่อใช้ไดเรกทีฟกับฟิลด์บางฟิลด์แล้ว export ค่าของมัน เราต้องใช้ @deferredExport แทน @export
  • เมื่อใช้ Multi-Field Directives ร่วมกับ @export (หรือ @deferredExport) ค่าที่ export ออกมาจะเป็น JSON object ที่มีทุกฟิลด์
  • Mutation Post.update จะมีในสคีมาเฉพาะเมื่อเปิดใช้งานฟีเจอร์ Nested Mutations เท่านั้น