当Lambda介于两者之间时,如何使用AppSync和DynamoDB正确格式化数据



使用AppSync直接从DynamoDB接收数据似乎适用于我的情况,但当我试图将lambda函数放在两者之间时,我收到的错误是"无法解析值(/issueNewMasterCards/masterCards(:类型不匹配错误,应为LIST类型">

查看AppSync cloudwatch响应映射输出,我得到了以下内容:

"context": {
"arguments": {
"userId": "18e946df-d3de-49a8-98b3-8b6d74dfd652"
},
"result": {
"Item": {
"masterCards": {
"L": [
{
"M": {
"cardId": {
"S": "95d67f80-b486-11e8-ba85-c3623f6847af"
},
"cardImage": {
"S": "https://s3.eu-central-1.amazonaws.com/logo.png"
},
"cardWallet": {
"S": "0xFDB17d12057b6Fe8c8c434653456435634565"
},...............

以下是我如何配置我的响应映射模板:

$utils.toJson($context.result.Item)

我正在做这个突变:

mutation IssueNewMasterCard {
issueNewMasterCard(userId:"18e946df-d3de-49a8-98b3-8b6d74dfd652"){
masterCards {
cardId
}
}
}

这是我的模式:

type User {
userId: ID!
masterCards: [MasterCard]
}
type MasterCard {
cardId: String
}
type Mutation {
issueNewMasterCard(userId: ID!): User
}

Lambda函数:

exports.handler = (event, context, callback) => {
const userId = event.arguments.userId;
const userParam = {
Key: {
"userId":{S:userId}
},
TableName:"FidelityCardsUsers"
}
dynamoDB.getItem(userParam, function(err, data) {
if (err) {
console.log('error from DynamDB: ',err)
callback(err);
} else {
console.log('mastercards: ',JSON.stringify(data));
callback(null,data)
}
})

我认为问题在于使用DynamoDB数据源时使用的getItem与aws-sdk中的DynamoDB.getItem函数不同。

具体来说,数据源版本似乎返回了一个已经整理好的响应(也就是说,它只返回something: [ list of things],而不是something: { L: [ list of things ] }(。

这一点很重要,因为这意味着当前设置中的$utils.toJson($context.result.Item)将返回{ masterCards: { L: [ ...,这就是您看到类型错误的原因——在这种情况下,masterCards是一个具有键L的对象,而不是数组/列表。

要在解析器中解决此问题,可以使用$util.dynamodb.toDynamoDBJson(Object)宏(https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference.html#dynamodb-util-dynolderdb中的助手(。即您的解析器应该是:

$util.dynamodb.toDynamoDBJson($context.result.Item)

或者,您可能希望查看AWS.DynamoDB.DocumentClient类(https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/DocumentClient.html)。这包括getItem等的版本,它们自动将专有的DynamoDB类型封送和取消封送回本地JSON。(坦率地说,我发现与它一起工作并一直使用它要好得多(。

在这种情况下,可以保留旧的解析器,因为您将返回一个对象,其中masterCards只是一个JSON数组。

最新更新