如果您可以发布您的架构/解析器映射模板,我可以提供更具体的建议,但我会尽力用您迄今为止发布的内容来回答这个问题。
简单的方法
如果您已经拥有现有项目,则执行此操作的一种方法是更新现有对并将其传递给现有突变。
const existingItem = {
id: "e5eb02ae-04d5-4331-91e6-11efaaf12ea5",
Pairs: [['a', 'b'],['c', 'd'],['e', 'f']]
}
const newPairs = {
number1: "g",
number2: "h"
}
const updateinfo = {
id: existingItem.id,
// Note that if existingItem.Pairs is always defined this can be simplified to
// Pairs: [...existingItem.Pairs, [newPairs.number1, newPairs.number2]]
Pairs: existingItem.Pairs ?
[...existingItem.Pairs, [newPairs.number1, newPairs.number2]] :
[[newPairs.number1, newPairs.number2]]
}
try {
await API.graphql(graphqlOperation (UpdateInfo, { input: updateinfo }))
//mutation
console.log('success')
}
catch (err) {
console.log(err)
}
使用 DynamoDB 函数
如果您没有现有物品或者如果Pairs
可能相当大,AWS DynamoDB 的list_append
可以使用函数代替。
list_append(操作数,操作数)
该函数计算出一个添加了新元素的列表。您可以通过反转操作数的顺序将新元素附加到列表的开头或结尾。
这是一个使用它的特定突变的示例。
### SDL
type Item {
id: ID!
Pairs: [[String]]
}
input AddPairInput {
id: ID!
number1: String!
number2: String!
}
type Mutation {
addPairToItem(input: AddPairInput!): Item!
}
...rest of schema omitted for brevity
### Resolver Request Mapping Template
{
"version": "2017-02-28",
"operation": "UpdateItem",
"key": {
"id": { "S": "$ctx.args.input.id"}
},
"update": {
### Note: we also use if_not_exists here so this works if Pairs is not yet defined on the item.
"expression":"SET Pairs = list_append(if_not_exists(Pairs, :emptyList), :newPair)",
"expressionValues":
{
":newPair":{"L": [{"L":[{"S":"$ctx.args.input.number1"},
{"S":"$ctx.args.input.number2"}]}]},
":emptyList":{"L": []}
}
}
}
### Resolver Response Mapping Template
$util.toJson($ctx.result)
这种方式也很好,因为如果其他人更新了 Pairs,您不会覆盖他们的更新。您还可以通过将参数的顺序反转来将新的 Pair 添加到列表的开头list_append
功能。
DynamoDB 函数与 AWS Amplify
如果您的项目是由 AWS Amplify 生成的,您将需要添加客户解析器 https://aws-amplify.github.io/docs/cli-toolchain/graphql#custom-resolvers.
第 1 步:向您的架构添加新的突变
### ./amplify/backend/api/<api_name>/schema.graphql
type Item @model {
id: ID!
Pairs: [[String]]
}
type Mutation {
addPairToItem(input: AddPairToItemInput!): Item!
}
input AddPairToItemInput {
id: ID!
number1: String!
number2: String!
}
步骤 2:添加解析器请求映射模板
### ./amplify/backend/api/<api_name>/resolvers/Mutation.addPairToItem.req.vtl
{
"version": "2017-02-28",
"operation": "UpdateItem",
"key": {
"id": { "S": "$ctx.args.input.id"}
},
"update": {
"expression":"SET Pairs = list_append(if_not_exists(Pairs, :emptyList), :newPair)",
"expressionValues":
{
":newPair":{"L": [{"L":[{"S":"$ctx.args.input.number1"},{"S":"$ctx.args.input.number2"}]}]},
":emptyList":{"L": []}
}
}
}
步骤 3:添加解析器响应映射模板
### ./amplify/backend/api/<api_name>/resolvers/Mutation.addPairToItem.res.vtl
$util.toJson($ctx.result)
步骤 4:将自定义解析器添加到 CustomResources 堆栈中
### ./amplify/backend/api/<api_name>/stacks/CustomResources.json
"Resources": {
// ...other resources may exist here
"AddPairToItemResolver": {
"Type": "AWS::AppSync::Resolver",
"Properties": {
"ApiId": {
"Ref": "AppSyncApiId"
},
"DataSourceName": "ItemTable",
"TypeName": "Mutation",
"FieldName": "addPairToItem",
"RequestMappingTemplateS3Location": {
"Fn::Sub": [
"s3://${S3DeploymentBucket}/${S3DeploymentRootKey}/resolvers/Mutation.addPairToItem.req.vtl",
{
"S3DeploymentBucket": {
"Ref": "S3DeploymentBucket"
},
"S3DeploymentRootKey": {
"Ref": "S3DeploymentRootKey"
}
}
]
},
"ResponseMappingTemplateS3Location": {
"Fn::Sub": [
"s3://${S3DeploymentBucket}/${S3DeploymentRootKey}/resolvers/Mutation.addPairToItem.res.vtl",
{
"S3DeploymentBucket": {
"Ref": "S3DeploymentBucket"
},
"S3DeploymentRootKey": {
"Ref": "S3DeploymentRootKey"
}
}
]
}
}
}
},
第 5 步:构建并部署新的更改
- Run
amplify api gql-compile
查看生成的代码中的新更改(可选)。
- Run
amplify push
部署您的更改。
现在你可以运行amplify api console
或者使用新生成的代码来测试新突变的更改。
要生成新代码,您可以运行amplify codegen
。然后你应该能够做这样的事情
import Amplify, { API, graphqlOperation } from "aws-amplify";
import * as mutations from './graphql/mutations';
// Mutation
const addPairToItem = {
id: '1',
number1: 'a',
number2: 'b'
};
const newItem = await API.graphql(graphqlOperation(mutations.addPairToItem, {input: addPairToItem}));
其他示例
请记住使用您添加的任何新解析器更新您的 CustomResources.json 文件。
将单个项目添加到标量值列表中
### ./amplify/backend/api/<api_name>/schema.graphql
type Item @model {
id: ID!
words: [String]
}
input AddWordInput {
id: ID!
word: String!
}
type Mutation {
addWordToItem(input: AddWordInput!): Item!
}
### ./amplify/backend/api/<api_name>/resolvers/Mutation.addWordToItem.req.vtl
{
"version": "2017-02-28",
"operation": "UpdateItem",
"key": {
"id": { "S": "$ctx.args.input.id"}
},
"update": {
"expression":"SET words = list_append(if_not_exists(words, :emptyList), :newWord)",
"expressionValues":
{
":newWord":{"L": [{"S":"$ctx.args.input.word"}]},
":emptyList":{"L": []}
}
}
}
### ./amplify/backend/api/<api_name>/resolvers/Mutation.addWordToItem.res.vtl
$util.toJson($ctx.result)
### Usage
import Amplify, { API, graphqlOperation } from "aws-amplify";
import * as mutations from './graphql/mutations';
// Mutation
const newWord = {
id: '1',
word: 'foo'
};
const newItem = await API.graphql(graphqlOperation(mutations.addWordToItem, {input: newWord}));
将多个项目添加到标量值列表
注:我介绍的是$util.dynamodb.toDynamoDBJson
在这里让构建我们的 VTL 变得更容易。到目前为止我已经很明确了,但是这个实用程序可以简化很多工作。更多这里 https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference.html#dynamodb-helpers-in-util-dynamodb
### ./amplify/backend/api/<api_name>/schema.graphql
type Item @model {
id: ID!
words: [String]
}
input AddWordsInput {
id: ID!
words: [String!]!
}
type Mutation {
addWordsToItem(input: AddWordsInput!): Item!
}
### ./amplify/backend/api/<api_name>/resolvers/Mutation.addWordsToItem.req.vtl
{
"version": "2017-02-28",
"operation": "UpdateItem",
"key": {
"id": { "S": "$ctx.args.input.id"}
},
"update": {
"expression":"SET words = list_append(if_not_exists(words, :emptyList), :newWords)",
"expressionValues":
{
":newWords": $util.dynamodb.toDynamoDBJson($ctx.args.input.words),
":emptyList": $util.dynamodb.toDynamoDBJson([])
}
}
}
### ./amplify/backend/api/<api_name>/resolvers/Mutation.addWordsToItem.res.vtl
$util.toJson($ctx.result)
### Usage
import Amplify, { API, graphqlOperation } from "aws-amplify";
import * as mutations from './graphql/mutations';
// Mutation
const newWords = {
id: '1',
words: ["bar","xyz","bar"]
};
const newItem = await API.graphql(graphqlOperation(mutations.addWordsToItem, {input: newWords}));
从标量值列表中删除项目
从 DynamoDB 中的列表中删除元素是使用 REMOVE 操作完成 https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.REMOVE.RemovingListElements。您必须指定非负索引作为更新表达式的一部分。如果该项目不存在索引,您的请求不会失败(例如,没有索引越界异常)。
type Item @model {
id: ID!
words: [String]
}
input RemoveWordInput {
id: ID!
wordIndex: Int!
}
type Mutation {
removeWordFromItem(input: RemoveWordInput!): Item!
}
### ./amplify/backend/api/<api_name>/resolvers/Mutation.removeWordFromItem.req.vtl
{
"version": "2017-02-28",
"operation": "UpdateItem",
"key": {
"id": { "S": "$ctx.args.input.id"}
},
"update": {
"expression":"REMOVE words[$ctx.args.input.wordIndex]"
}
}
### ./amplify/backend/api/<api_name>/resolvers/Mutation.removeWordFromItem.res.vtl
$util.toJson($ctx.result)
### Usage
import Amplify, { API, graphqlOperation } from "aws-amplify";
import * as mutations from './graphql/mutations';
// Mutation
const removeWord = {
id: '1',
// The index is 0 based so wordIndex: 0
// would delete the first item,
// wordIndex: 1 deletes the second, etc.
wordIndex: 1
};
const newItem = await API.graphql(graphqlOperation(mutations.removeWordFromItem, {input: removeWord}));