将AWS移动后端连接到DynamoDB

时间:2019-03-08 09:38:49

标签: amazon-web-services amazon-dynamodb

我正在尝试使用AWS移动后端(使用lambda函数)插入dynamoDB(也在移动后端配置),但到目前为止没有成功。

相关代码:

'use strict';
console.log("Loading function");

const AWS = require('aws-sdk');
const docClient = new AWS.DynamoDB.DocumentClient({region:process.env.MOBILE_HUB_PROJECT_REGION});



exports.handler = function(event, context, callback) {
    var responseCode = 200;
    var requestBody, pathParams, queryStringParams, headerParams, stage,
    stageVariables, cognitoIdentityId, httpMethod, sourceIp, userAgent,
    requestId, resourcePath;
    console.log("request: " + JSON.stringify(event));

    // Request Body
    requestBody = event.body;

    if (requestBody !== undefined && requestBody !== null) {

        // Set 'test-status' field in the request to test sending a specific response status code (e.g., 503)
        responseCode = JSON.parse(requestBody)['test-status'];
    }

    // Path Parameters
    pathParams = event.path;

    // Query String Parameters
    queryStringParams = event.queryStringParameters;

    // Header Parameters
    headerParams = event.headers;

    if (event.requestContext !== null && event.requestContext !== undefined) {

        var requestContext = event.requestContext;

        // API Gateway Stage
        stage = requestContext.stage;

        // Unique Request ID
        requestId = requestContext.requestId;

        // Resource Path
        resourcePath = requestContext.resourcePath;

        var identity = requestContext.identity;

        // Amazon Cognito User Identity
        cognitoIdentityId = identity.cognitoIdentityId;

        // Source IP
        sourceIp = identity.sourceIp;

        // User-Agent
        userAgent = identity.userAgent;
    }

    // API Gateway Stage Variables
    stageVariables = event.stageVariables;

    // HTTP Method (e.g., POST, GET, HEAD)
    httpMethod = event.httpMethod;

    // TODO: Put your application logic here...

    let params = {
        Item:{
            "prop1":0,
            "prop2":"text"
        },
        TableName:"testTable"
    };

    docClient.put(params, function(data, err){
        if(err)
            responseCode = 500;
        else
            {
                responseCode = 200;
                context.succeed(data);
            }
    });

    // For demonstration purposes, we'll just echo these values back to the client
    var responseBody = {
        requestBody : requestBody,
        pathParams : pathParams,
        queryStringParams : queryStringParams,
        headerParams : headerParams,
        stage : stage,
        stageVariables : stageVariables,
        cognitoIdentityId : cognitoIdentityId,
        httpMethod : httpMethod,
        sourceIp : sourceIp,
        userAgent : userAgent,
        requestId : requestId,
        resourcePath : resourcePath
    };

    var response = {
        statusCode: responseCode,
        headers: {
            "x-custom-header" : "custom header value"
        },
        body: JSON.stringify(responseBody)
    };
    console.log("response: " + JSON.stringify(response))
    context.succeed(response);
};

由于某种原因,这不会将商品放到桌子上。 我使用角色部分授予了必要的权限,我缺少什么?

** responseCode仅用于测试目的。

编辑: 尝试过AWS node.js lambda request dynamodb but no response (no err, no return data),但也不起作用。

Edit2: 添加了完整的处理程序代码。 (它是创建第一个AWS Lambda时默认生成的代码)。

2 个答案:

答案 0 :(得分:1)

我将代码的某些部分重构为看起来更简单,并使用async/await(确保将Node 8.10选择为函数的运行环境)而不是回调。我还摆脱了上下文和回调参数,因为它们用于旧版本的NodeJS。使用Node 8+之后,应将async / await作为默认选项。

此外,还可以在docClient.putItem上链接.promise(),因此您可以轻松地等待它,从而使代码更简单。我只剩下了D​​ynamoDB部分(这与您的问题有关)

'use strict';
console.log("Loading function");

const AWS = require('aws-sdk');
const docClient = new AWS.DynamoDB.DocumentClient({region:process.env.MOBILE_HUB_PROJECT_REGION});

exports.handler = async (event) => {

    let params = {
        Item:{
            "prop0":1,
            "prop2":"text"
        },
        TableName:"testTable"
    };

    try {
      await docClient.put(params).promise();
    } catch (e) {
      console.log(e)
      return {
        messsage: e.message
      }
    }

    return { message: 'Data inserted successfully' };

};

如果仍然无法解决,请记住以下几点:

  1. 确保您的Lambda函数具有在DynamoDB上插入项目的正确权限(AmazonDynamoDBFullAccess会这样做)

  2. 将项目插入DynamoDB时,您始终必须提供分区键。在您的示例中,JSON仅具有两个属性:prop1和prop2。如果它们都不是分区键,那么您的代码肯定会失败。

  3. 确保您的表也存在

如果代码失败,只需检查CloudWatch日志,因为现在捕获了任何异常并将其打印在控制台上。

答案 1 :(得分:1)

之所以没有在表中写入数据,是因为对DynamoDB put的调用是异步的,将通过调用回调返回。但是在这段时间内,其余代码将继续执行,并且您的函数最终会在对DynamoDB的调用有机会完成之前完成。

您可以使用await / async关键字使代码同步:

async function writeToDynamoDB(params) {
 return new Promise((resolve,reject) => {
    docClient.put(params, function(data, err){
        if(err)
            reject(500);
        else
            resolve(data);
     });
 });
}

let params = ...
var data = await writeToDynamoDB(params)

您可以在https://github.com/sebsto/maxi80-alexa/blob/master/lambda/src/DDBController.ts

处找到我编写的(在Typescript中)示例代码。