让 DynamoDB Stream Lambda 函数调用 AWS AppSync 突变

Posted

技术标签:

【中文标题】让 DynamoDB Stream Lambda 函数调用 AWS AppSync 突变【英文标题】:Make the DynamoDB Stream Lambda function call the AWS AppSync mutation 【发布时间】:2019-07-27 06:48:24 【问题描述】:

我有一个 lambda 函数,当我的 dynamodb 表发生更改时会触发该函数。当我使用 lambda 解析器时,我只能从我的 appsync 中调用一个 lambda 函数,这不是我想要做的。

我正在尝试遵循此处提供的答案:

How do I subscribe directly to my AWS AppSync data source?

但我在第 3 步时遇到问题。

谢谢

按照@Aaron_H 的回答,这是我的 lambda 函数:

module.exports.triggerStream = async (event, context, callback) => 
if(event.Records[0].eventName === 'INSERT')
return new Promise((resolve, reject) => 
    console.log(event.Records[0].eventName)
    console.log(JSON.stringify(context))
    console.log(JSON.stringify(event));


        const myData =  //this part is hardcoded for my tests
            "query": `
            mutation UpdateData($myDeviceID : String!, $myTs : String!, $myPayload: payloadInput)
                updateData(deviceID : $myDeviceID, ts : $myTs, payload : $myPayload)
                    checkup
                
            
            `,
            "variables": 
                "myDeviceID": "z55-temp",
                "myTs": "1549512000",
                "myPayload":
                    "deviceId": "z55-temp",
                    "ts": 1549512000,
                    "value": 17.25
                
            
        ;
    const data=JSON.stringify(myData)

    const options = 
        host: 'blablabla.appsync-api.us-east-1.amazonaws.com',
        path: '/graphql',
        method: 'POST',
        headers: 'Content-Type': 'application/json',
            "X-Api-Key" : "myApiKey"           
    ;      

    var req = https.request(options, (res) => 
      console.log('statusCode:', res.statusCode);
      console.log('headers:', res.headers);
      res.setEncoding('utf8');
      resolve('Success');

      res.on('data', (d) => 
        process.stdout.write(d);

      );
    );

    req.on('error', (e) => 
      console.error(e);
      reject(e.message);
    );
    // send the request
    req.write(data);
    req.end();
);

;

我也在使用无服务器框架,这是我的 lambda 函数的 serverless.yml 配置:

function:triggerStream:
handler: handler.triggerStream
events:
   - stream:
      type: dynamodb
      batchSize: 1
      startingPosition: LATEST
      arn: myExistingTableArn    

我的问题是我想使用 Amazon Cognito 用户池进行我的 appsync 授权。如果我的请求来自 Dynamodb 流,我应该如何在我的标头中使用 JWT 令牌?我有一个在我的表中插入数据的 IOT 设备。

谢谢!

【问题讨论】:

【参考方案1】:

在 Michael 在附加的 SO 问题中概述的解决方案中,您没有使用任何 Lambda 类型的解析器。相反,您正在设置 DynamoDB 流来触发 Lambda 函数(如https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.Lambda.html 中所述)。然后,该 lambda 函数中的代码采用 DynamoDB 中更改的数据来调用您的 AppSync 终端节点。确保将任何必要的身份验证标头与来自 Lambda 的请求一起发送。

+--------+     +---------------+     +----------------+
|DynamoDB| --> |Lambda Function| --> |AppSync mutation|
+--------+     +---------------+     +----+-----+-----+
                                          |     |
                                     +----+     +----+
                                     v               v
                               +----------+    +----------+
                               |AppSync   |    |AppSync   |
                               |subscriber|    |subscriber|
                               +----------+    +----------+

您发送到 appsync 端点的特定操作是您添加的突变,它没有数据源(NONE 类型数据源),并使用本地解析器重新广播发送到该端点的任何数据对已提出订阅请求的任何订阅者进行突变。需要注意的关键点是 DynamoDB 触发的是 Lambda,而不是 AppSync。

【讨论】:

谢谢!我知道有一个 lambda 函数,当在我的 Dynamodb 表中插入一个项目时会触发该函数,然后 lambda 函数调用一个突变。除了授权标头外,一切正常。我使用了标头中指定的 api-key,但是在使用 amazon cognito 用户池时,我很迷茫。如果调用来自 dynamodb 流,我如何检索 JWT?我有一个在我的表中插入数据的物联网设备。 您可以选择将后端用户的 JWT 嵌入到您的 Lambda 函数中,或者选择一个用户名和密码,Lambda 可以使用该用户名和密码从 Cognito 检索 JWT,然后将其添加到AppSync 变更调用中的授权标头。 谢谢!我在后端使用了带有 ADMIN_NO_SRP_AUTH 的 adminInitiateAuth,它就像我想要的那样工作! dynamoDB 流是否可以直接触发appsync 订阅?假设我有两个修改同一个 Dynamo 表的 appsync,我希望一个 appsync 接口将更新发送到另一个 appsync 端点。

以上是关于让 DynamoDB Stream Lambda 函数调用 AWS AppSync 突变的主要内容,如果未能解决你的问题,请参考以下文章

Lambda 和 DynamoDB:无权执行:dynamodb:Scan

从 DynamoDB 触发 lambda 函数

配置dynamoDb流仅在删除时调用lambda函数

Lambda 函数在 DynamoDB 事件上触发了两次

使用 lambda 扫描/查询 dynamodb 表中的特定条目

使用 Lambda 将 Json 添加到 DynamoDB