发布 AWS Amplify GraphQL 突变时如何避免在数组中创建重复项
Posted
技术标签:
【中文标题】发布 AWS Amplify GraphQL 突变时如何避免在数组中创建重复项【英文标题】:How to avoid creating duplicate items in an array when posting an AWS Amplify GraphQL mutation 【发布时间】:2020-11-27 23:45:03 【问题描述】:前言:我是 GraphQL 和 Amplify 的新手。
我有一个包含两个数组的用户对象,一个名为preferred_genres
,另一个名为preferred_characters
。我有一个个人资料页面,用户可以在其中编辑他们的个人资料并将项目添加到这些数组中。
AWS Amplify 提供的更新突变似乎只是将元素添加到数组中,而不会删除它们。如果在我的 UI 上我从列表中删除一个项目,然后提交更新突变,则该项目不会从我的后端中删除。如果我将一个项目添加到数组中,该项目将添加到后端,但我最终也会得到那些已经在后端的重复值。
我想要做的是用我从前端提交的数据覆盖后端的数组。我错过了一些明显的东西吗?在 GraphQL 中是否有更合适的方法来实现这一点?
架构
type User @model
id: ID!
...
preferred_characters: [Character]
preferred_genres: [Genre]
...
【问题讨论】:
【参考方案1】:DataStore 的冲突解决文档:
更新冲突解决方案:
-
一种方法是按照documentation 的建议更新它(我这样做的方式)。
-
我检查了哪些文件发生了变化,唯一重要的更新密钥可以在
amplify/backend/api/<yourApi>/transform.conf.json
中找到
发件人:
收件人:
【讨论】:
通过上述方法,我的项目目前没有被复制。我正在密切关注它。如果重复出现,我会更新答案。【参考方案2】:我偶然发现了 this question in the Amplify GitHub issues 关于 AWSJSON 标量有类似问题的信息。该问题似乎与 API 中的 conflict resolution 有关。
我不记得设置了,但我尝试了 amplify update API
,选择了我的 GraphQL API 和高级选项,拒绝任何冲突解决并运行 amplify push
。
现在值按预期保存。当我从数组中删除一个项目时,它会从后端删除,反之亦然。
【讨论】:
您是如何禁用冲突解决的?在 CLI 中,我看到的只是不配置冲突解决的选项,但这听起来不像是禁用它。 这是几个月前的事了,所以我记不清了。备份您的放大配置并尝试不配置冲突解决选项并放大推送。如果它没有帮助,那么您可以恢复到以前的配置。【参考方案3】:实现这一点的一种方法是更改您的 updateUser 解析器以更新或创建这些条目。
"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)
More details
【讨论】:
感谢您的回复。我对这个看似简单的要求有多少间接性感到非常震惊:更新用户对象上的数组。我知道 Amplify 会为您生成大量代码,但成本是多少?为了进行最简单的更改,您需要学习编写 Apache Velocity 模板语言模板吗?只看他们文档中的示例就让我头晕目眩。 宣讲它@Roy。我现在几乎遇到了这个确切的问题,我已经等了好几个星期才让有人回答我的问题。 同样的,面临同样的问题,仍然找不到直接的解决方案以上是关于发布 AWS Amplify GraphQL 突变时如何避免在数组中创建重复项的主要内容,如果未能解决你的问题,请参考以下文章
发布 AWS Amplify GraphQL 突变时如何避免在数组中创建重复项
AWS Amplify + Graphql + Dynamodb:突变时出现 ConditionalCheckFailedException 错误
在反应本机应用程序中使用 AWS Amplify 在 GraphQL 突变中出错
AWS Amplify CLI 生成的 GraphQL 突变中的 $condition 输入参数是啥?
使用 AWS Amplify Auth 和 GraphQL API,您将如何进行一些公共和一些私有查询/突变调用?
我可以使用 aws amplify 和 @auth 装饰器将 GraphQL 突变设为私有吗?这被认为是一种安全的方法吗?