【问题标题】:How to create a lambda function to update a new record on amplify?如何创建一个 lambda 函数来更新放大的新记录?
【发布时间】:2020-08-03 03:00:06
【问题描述】:

如何使用 GraphQL 创建 lambda 函数来更新 amplify 项目的新记录?

我有一个使用 api GraphQL 作为 api(也是 dynamoDB)的放大项目。

我的应用程序是一个简单的待办事项列表,只是为了学习,所以我将待办事项保存在我的 dynamoDB 上,这就是我的架构:

type Todo @model @auth(rules: [{ allow: owner }]) {
    id: ID!
    title: String!
    status: String
}

当我创建一个新的待办事项时,我只设置标题,而不是状态,我想使用 lambda 触发器函数用默认值更新状态(我知道我不必这样做,但我我正在尝试学习更多关于放大的 lambda 函数)。

所以我按照amplify docs 的步骤进行操作,但现在我不知道下一步是什么(我不熟悉 aws lambda 函数)。

我想做的事情是这样的:

for each new record
newRecord.status = 'To do'
newRecord.update()

【问题讨论】:

    标签: javascript reactjs aws-lambda database-trigger aws-amplify


    【解决方案1】:

    当您首次创建 Todo 项目时,它会作为项目存储在 DynamodDB 表中。要更新待办事项,您需要更新 DynamoDB 表中的项目。

    当您更新 DynamoDB 中的项目时,您需要使用 AWS 开发工具包来处理此问题。如果您在 lambda 函数中使用 nodejs,最简单的 sdk 是使用 AWS DynamoDB Document Client

    // Load the AWS SDK for Node.js
    var AWS = require('aws-sdk');
    // Set the region
    AWS.config.update({region: 'REGION'}); //replace Region with the region you are using ('EU-WEST-1')
    
    // Create DynamoDB document client
    var docClient = new AWS.DynamoDB.DocumentClient({apiVersion: '2012-08-10'});
    
    
    // put the the following code in the exports.handler in your lambda function
    var params = {
      TableName: 'Todo-SOMERANDOMSTRING-ENV',//The name of your dynamodb table
      Key: {
        'id' : 'asasd123-asdsa1-12sdasads-12', // the id of your todo item
      },
      UpdateExpression: 'set status = :s',
      ExpressionAttributeValues: {
        ':s' : 'To do' // what the new status should be
      }
    };
    // and run the update function
    docClient.update(params, function(err, data) {
      if (err) {
        console.log("Error", err);
      } else {
        console.log("Success", data);
      }
    });
    

    编辑

    根据您的评论,我认为您可能在 DynamoDB Lambda 触发器部分 (?),您的样板 lambda 函数可能如下所示:

    exports.handler = function (event, context) {
      console.log(JSON.stringify(event, null, 2));
      event.Records.forEach((record) => {
        console.log(record.eventID);
        console.log(record.eventName);
        console.log('DynamoDB Record: %j', record.dynamodb);
      });
      context.done(null, 'Successfully processed DynamoDB record');
    };
    

    我自己之前没有做过这种类型的触发器,所以我不完全确定记录中的数据是如何构造的,但我认为它可能会像这样访问:

    record.data.id
    //or
    record.Item.id
    

    您可以通过转至 lambda 控制台找到并打开您的 lambda 函数,转至“监控”,然后在 AWS 中打开“查看 CloudWatch 中的日志”,并在创建项目后检查 CloudWatch 日志。

    假设它是 record.Item.id,您的 lambda 代码可能如下所示(未经测试):

    var AWS = require('aws-sdk');
    AWS.config.update({region: 'REGION'});
    var docClient = new AWS.DynamoDB.DocumentClient({apiVersion: '2012-08-10'});
    
    exports.handler = function (event, context) {
      console.log(JSON.stringify(event, null, 2));
         event.Records.forEach((record) => {
            var params = {
               TableName: 'YOUR-DB-TABLE-NAME',
               Key: {
                  'id' : record.Item.id,
               },
               UpdateExpression: 'set status = :status',
               ExpressionAttributeValues: {
                  ':status' : 'To do' // what the new status should be
               }
            };
            docClient.update(params, function(err, data) {
               if (err) {
                  console.log("Error", err);
               } else {
                  console.log("Success", data);
               }
            });
          });
       context.done(null, 'Successfully processed DynamoDB record');
     };
    

    我认为这段代码并不完整,您可能需要更改“context.done”函数的工作方式/时间(因为我认为它会在代码完成更新项目之前运行),但它可能让您朝着正确的方向前进。

    【讨论】:

    • 非常感谢!只有一件事,要访问我的新记录的 id,我应该使用 event.Records.forEach((record) => ... 然后查找 INSERT 操作,然后查找对象吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-18
    • 2017-08-23
    相关资源
    最近更新 更多