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.
updatePost(
id: ID!,
author: String!,
title: String!,
content: String!,
url: String!
): Post
{
"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 }
}
}
}
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”.
$utils.toJson($context.result)
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
}
}
{
"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
}
}
}
Sau khi thực hiện sau 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:
updatePost(
id: ID!,
author: String,
title: String,
content: String,
url: String,
expectedVersion: Int!
): Post
Trong ngăn Resolvers ở bên phải, tìm trường updatePost trên kiểu Mutation, sau đó chọn Attach
Dán nội dung dưới đây vào mục Configure the request mapping template
{
"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)
}
}
}
mutation updatePost {
updatePost(
id:123
title: "An empty story"
content: null
expectedVersion: 2
) {
id
author
title
content
url
ups
downs
version
}
}
{
"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
}
}
}
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.
Yêu cầu không thành công vì biểu thức điều kiện thực hiện sai:
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
upvotePost(id: ID!): Post
downvotePost(id: ID!): Post
{
"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 }
}
}
}
$utils.toJson($context.result)
{
"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 }
}
}
}
$utils.toJson($context.result)
mutation votePost {
upvotePost(id:123) {
id
author
title
content
url
ups
downs
version
}
}
{
"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
}
}
}
mutation votePost {
downvotePost(id:123) {
id
author
title
content
url
ups
downs
version
}
}