Cập nhật dữ liệu

Trong bước này chúng ta sẽ tạo một Mutation mới cho phép cập nhật đối tượng trong bảng của DynamoDB. Chúng ta sẽ sử dụng UpdateItem của DynamoDB.

Cập nhật bài đăng

  1. Chọn tab Schema
  • Thêm đoạn code dưới đây vào kiểu Mutation để thêm một mutation mới là updatePost
  • Sau đó ấn Save Schema
    updatePost(
        id: ID!,
        author: String!,
        title: String!,
        content: String!,
        url: String!
    ): Post

CreateAddPostResolver

  1. Trong ngăn Resolvers ở bên phải, tìm trường updatePost thuộc kiểu Mutation, sau đó chọn Attach

CreateAddPostResolver

  1. Tại trang cấu hình Attach resolver:
  • Resolver type: Chọn Unit resolver
  • Resolver runtime: Chọn Velocity Template Language (VTL)
  • Data source name: Chọn PostDynamoDBTable
  • Kéo xuống dưới cùng và ấn nút Create màu cam.

CreateGetResolvers

  1. Sau khi tạo xong, bạn sẽ được chuyển đến trang soạn thảo mã của Resolver. Tại đây:
  • Xóa mã mặc định và dán nội dung dưới đây vào phần Configure the request mapping template (Mẫu ánh xạ yêu cầu):
{
    "version" : "2017-02-28",
    "operation" : "UpdateItem",
    "key" : {
        "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id)
    },
    "update" : {
        "expression" : "SET author = :author, title = :title, content = :content, #url = :url ADD version :one",
        "expressionNames": {
            "#url" : "url"
        },
        "expressionValues": {
            ":author" : $util.dynamodb.toDynamoDBJson($context.arguments.author),
            ":title" : $util.dynamodb.toDynamoDBJson($context.arguments.title),
            ":content" : $util.dynamodb.toDynamoDBJson($context.arguments.content),
            ":url" : $util.dynamodb.toDynamoDBJson($context.arguments.url),
            ":one" : { "N": 1 }
        }
    }
}

CreateAddPostResolver

Resolver này đang sử dụng DynamoDB UpdateItem, khác biệt đáng kể với hoạt động PutItem. Thay vì viết toàn bộ mục, bạn chỉ yêu cầu DynamoDB cập nhật một số thuộc tính nhất định. Để làm được điều này cần sử dụng DynamoDB Update Expressions. Bạn có thể thấy phần “expression” trong mục “update”. Nó cho biết đặt thuộc tính author, title, content và url, sau đó tăng trường version. Expression có các placeholder có tên bắt đầu bằng dấu hai chấm, sau đó được xác định trong trường “expressionValues”. Cuối cùng, DynamoDB có các từ dành riêng không thể xuất hiện trong expression. Ví dụ: url là một từ dành riêng, do đó, để cập nhật trường url, bạn có thể sử dụng placeholder tên và xác định chúng trong trường “expressionNames”.

  1. Kéo xuống dưới, xóa mã mặc định và dán nội dung dưới đây vào mục Configure the response mapping template (Mẫu ánh xạ phản hồi):
#if($context.error)
  $util.error($context.error.message, $context.error.type)
#end
$util.toJson($context.result)

CreateAddPostResolver

  1. Ấn Save ở góc trang để lưu lại

CreateAddPostResolver

  1. Chọn tab Queries ở menu bên trái để thực hiện gọi API để cập nhật một bài đăng
  • Xóa mã mặc định trong khung soạn thảo, dán đoạn lệnh dưới đây vào phần Queries, sau đó ấn nút Run (biểu tượng nút Play màu cam)
mutation updatePost {
  updatePost(
    id:"123"
    author: "A new author"
    title: "An updated author!"
    content: "Now with updated content!"
    url: "https://aws.amazon.com/appsync/"
  ) {
    id
    author
    title
    content
    url
    ups
    downs
    version
  }
}

CreateAddPostResolver

  1. Kết quả trả về tương tự như sau:
{
  "data": {
    "updatePost": {
      "id": "123",
      "author": "A new author",
      "title": "An updated author!",
      "content": "Now with updated content!",
      "url": "https://aws.amazon.com/appsync/",
      "ups": 1,
      "downs": 0,
      "version": 2
    }
  }
}

CreateAddPostResolver

Sau khi thực hiện xong việc cập nhật, thuộc tính version được tăng lên một đơn vị vì chúng ta đã yêu cầu AWS AppSync và DynamoDB thêm một đơn vị cho thuộc tính version mỗi khi cập nhật.

Khi bạn sử dụng mutation updatePost như trên sẽ xảy ra 2 vấn đề sau:

  • Nếu bạn chỉ muốn cập nhật một trường duy nhất, bạn phải cập nhật tất cả các trường.
  • Nếu hai người đang sửa đổi đối tượng, bạn có thể bị mất thông tin. Thực hiện các bước tiếp theo để khắc phục vấn đề trên
  1. Chọn tab Schema ở menu bên trái
  • Thay thế code của mutation updatePost bằng nội dung dưới đây:
  • Sau đó ấn Save Schema
    updatePost(
        id: ID!,
        author: String,
        title: String,
        content: String,
        url: String,
        expectedVersion: Int!
    ): Post

CreateAddPostResolver

  1. Trong ngăn Resolvers ở bên phải, tìm trường updatePost thuộc kiểu Mutation, sau đó click vào tên data source PostDynamoDBTable để sửa Resolver hiện tại.

CreateAddPostResolver

  1. Tại trang soạn thảo mã:
  • Xóa mã cũ và dán nội dung dưới đây vào mục Configure the request mapping template (Mẫu ánh xạ yêu cầu):
{
    "version" : "2017-02-28",
    "operation" : "UpdateItem",
    "key" : {
        "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id)
    },

    ## Set up some space to keep track of things you're updating **
    #set( $expNames  = {} )
    #set( $expValues = {} )
    #set( $expSet = {} )
    #set( $expAdd = {} )
    #set( $expRemove = [] )

    ## Increment "version" by 1 **
    $!{expAdd.put("version", ":one")}
    $!{expValues.put(":one", { "N" : 1 })}

    ## Iterate through each argument, skipping "id" and "expectedVersion" **
    #foreach( $entry in $context.arguments.entrySet() )
        #if( $entry.key != "id" && $entry.key != "expectedVersion" )
            #if( (!$entry.value) && ("$!{entry.value}" == "") )
                ## If the argument is set to "null", then remove that attribute from the item in DynamoDB **

                #set( $discard = ${expRemove.add("#${entry.key}")} )
                $!{expNames.put("#${entry.key}", "$entry.key")}
            #else
                ## Otherwise set (or update) the attribute on the item in DynamoDB **

                $!{expSet.put("#${entry.key}", ":${entry.key}")}
                $!{expNames.put("#${entry.key}", "$entry.key")}
                $!{expValues.put(":${entry.key}", { "S" : "${entry.value}" })}
            #end
        #end
    #end

    ## Start building the update expression, starting with attributes you're going to SET **
    #set( $expression = "" )
    #if( !${expSet.isEmpty()} )
        #set( $expression = "SET" )
        #foreach( $entry in $expSet.entrySet() )
            #set( $expression = "${expression} ${entry.key} = ${entry.value}" )
            #if ( $foreach.hasNext )
                #set( $expression = "${expression}," )
            #end
        #end
    #end

    ## Continue building the update expression, adding attributes you're going to ADD **
    #if( !${expAdd.isEmpty()} )
        #set( $expression = "${expression} ADD" )
        #foreach( $entry in $expAdd.entrySet() )
            #set( $expression = "${expression} ${entry.key} ${entry.value}" )
            #if ( $foreach.hasNext )
                #set( $expression = "${expression}," )
            #end
        #end
    #end

    ## Continue building the update expression, adding attributes you're going to REMOVE **
    #if( !${expRemove.isEmpty()} )
        #set( $expression = "${expression} REMOVE" )

        #foreach( $entry in $expRemove )
            #set( $expression = "${expression} ${entry}" )
            #if ( $foreach.hasNext )
                #set( $expression = "${expression}," )
            #end
        #end
    #end

    ## Finally, write the update expression into the document, along with any expressionNames and expressionValues **
    "update" : {
        "expression" : "${expression}"
        #if( !${expNames.isEmpty()} )
            ,"expressionNames" : $utils.toJson($expNames)
        #end
        #if( !${expValues.isEmpty()} )
            ,"expressionValues" : $utils.toJson($expValues)
        #end
    },

    "condition" : {
        "expression"       : "version = :expectedVersion",
        "expressionValues" : {
            ":expectedVersion" : $util.dynamodb.toDynamoDBJson($context.arguments.expectedVersion)
        }
    }
}

CreateAddPostResolver

  • Sau đó ấn Save ở góc trang.
  1. Chọn tab Queries ở menu bên trái để gọi API cập nhật một bài đăng
  • Xóa đoạn mã trong khung soạn thảo, dán đoạn lệnh dưới đây vào phần Queries, sau đó ấn nút Run (biểu tượng Play màu cam)
mutation updatePost {
  updatePost(
    id:123
    title: "An empty story"
    content: null
    expectedVersion: 2
  ) {
    id
    author
    title
    content
    url
    ups
    downs
    version
  }
}

CreateAddPostResolver

  1. Kết quả trả về tương tự như sau:
{
  "data": {
    "updatePost": {
      "id": "123",
      "author": "A new author",
      "title": "An empty story",
      "content": null,
      "url": "https://aws.amazon.com/appsync/",
      "ups": 1,
      "downs": 0,
      "version": 3
    }
  }
}

CreateAddPostResolver

Trong yêu cầu này, chúng ta yêu cầu AWS AppSync và DynamoDB chỉ cập nhật trường title và content, giữ nguyên các trường khác trừ việc tăng trường version.

  1. Thử ấn nút Run lần nữa, kết quả trả về tương tự như sau:

CreateAddPostResolver

Yêu cầu không thành công vì biểu thức điều kiện thực hiện sai:

  • Lần đầu tiên chạy, giá trị của trường version của bài đăng trong DynamoDB là 2, khớp với expectedVersion. Yêu cầu thành công, có nghĩa là trường phiên bản đã được tăng trong DynamoDB lên 3.
  • Lần thứ hai chạy, giá trị của trường version của bài đăng trong DynamoDB là 3, không khớp với expectedVersion.

Cập nhật số lượng bình chọn

Chúng ta sẽ tạo hai mutation mới để cập nhật trường ups và downs để ghi lại lượt ủng hộ hay phản đối cho bài đăng

  1. Chọn tab Schema
  • Thêm đoạn code dưới đây vào kiểu Mutation để thêm hai mutation mới là upvotePost và downvotePost
    upvotePost(id: ID!): Post
    downvotePost(id: ID!): Post
  • Sau đó ấn Save Schema

  • Tiếp theo trong ngăn Resolvers ở bên phải, tìm trường upvotePost thuộc kiểu Mutation, sau đó chọn Attach

CreateAddPostResolver

  1. Tại trang cấu hình Attach resolver:
  • Resolver type: Chọn Unit resolver
  • Resolver runtime: Chọn Velocity Template Language (VTL)
  • Data source name: Chọn PostDynamoDBTable
  • Ấn nút Create màu cam.
  1. Tại trang soạn thảo mã của Resolver vừa tạo:
  • Xóa mã mặc định và dán nội dung dưới đây vào phần Configure the request mapping template (Mẫu ánh xạ yêu cầu):
{
    "version" : "2017-02-28",
    "operation" : "UpdateItem",
    "key" : {
        "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id)
    },
    "update" : {
        "expression" : "ADD ups :plusOne, version :plusOne",
        "expressionValues" : {
            ":plusOne" : { "N" : 1 }
        }
    }
}
  • Kéo xuống dưới, xóa mã mặc định và dán nội dung dưới đây vào mục Configure the response mapping template (Mẫu ánh xạ phản hồi):
#if($context.error)
  $util.error($context.error.message, $context.error.type)
#end
$util.toJson($context.result)
  • Ấn Save ở góc trang để lưu lại

CreateAddPostResolver

  1. Chọn tab Schema ở menu bên trái
  • Trong ngăn Resolvers ở bên phải, tìm trường downvotePost thuộc kiểu Mutation, sau đó chọn Attach

CreateAddPostResolver

  1. Tại trang cấu hình Attach resolver:
  • Resolver type: Chọn Unit resolver
  • Resolver runtime: Chọn Velocity Template Language (VTL)
  • Data source name: Chọn PostDynamoDBTable
  • Ấn nút Create màu cam.
  1. Tại trang soạn thảo mã của Resolver vừa tạo:
  • Xóa mã mặc định và dán nội dung dưới đây vào phần Configure the request mapping template (Mẫu ánh xạ yêu cầu):
{
    "version" : "2017-02-28",
    "operation" : "UpdateItem",
    "key" : {
        "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id)
    },
    "update" : {
        "expression" : "ADD downs :plusOne, version :plusOne",
        "expressionValues" : {
            ":plusOne" : { "N" : 1 }
        }
    }
}
  • Kéo xuống dưới, xóa mã mặc định và dán nội dung dưới đây vào mục Configure the response mapping template (Mẫu ánh xạ phản hồi):
#if($context.error)
  $util.error($context.error.message, $context.error.type)
#end
$util.toJson($context.result)
  • Ấn Save ở góc trang để lưu lại

CreateAddPostResolver

  1. Chọn tab Queries ở menu bên trái
  • Xóa mã mặc định, dán đoạn lệnh dưới đây vào phần Queries, sau đó ấn nút Run (biểu tượng Play màu cam)
mutation votePost {
  upvotePost(id:"123") {
    id
    author
    title
    content
    url
    ups
    downs
    version
  }
}
  1. Kết quả trả về tương tự như sau:
{
  "data": {
    "upvotePost": {
      "id": "123",
      "author": "A new author",
      "title": "An empty story",
      "content": null,
      "url": "https://aws.amazon.com/appsync/",
      "ups": 2,
      "downs": 0,
      "version": 4
    }
  }
}

CreateAddPostResolver

  1. Đổi lệnh truy vấn thành downvotePost
mutation votePost {
  downvotePost(id:"123") {
    id
    author
    title
    content
    url
    ups
    downs
    version
  }
}
  • Ấn nút Run (biểu tượng Play màu cam)

CreateAddPostResolver

  1. Ấn nút Run (biểu tượng Play màu cam) lần nữa bạn sẽ thấy trường “downs” tăng lên