Dynamodb.put 在 运行 lambda 测试配置时工作正常,但在通过 API 网关调用 lambda 时无效

Dynamodb.put works fine when running a lambda test configuration, but not when invoking the lambda through API gateway

我有一个 API 网关,它触发了一个 Lambda 函数。 Lambda 函数然后将一个项目写入 DynamoDb。 API 网关可以正常访问并触发 Lambda 函数,因为我可以在发送 POST 请求后看到 CloudWatch 日志。

Lambda 函数的代码如下:

const AWS = require('aws-sdk');

const dynamodb = new AWS.DynamoDB.DocumentClient({region: 'eu-west-1'});

exports.handler = async (event) => {
    console.log("event.body contents", event.body);
    console.log("Inserting into DynamoDb...");
    await dynamodb.put(event.body).promise();
    return {
        statusCode: 200,
        body: JSON.stringify({message: 'Success'})
    };

};

我 运行 测试配置,以下输入进入 event:

{
  "body": {
    "TableName": "TestTable",
    "Item": {
      "IngameName": "SomeName",
      "Timestamp": "Fri Oct 09 2020 12:26:12 GMT+0100 (British Summer Time)",
    }
  }
}

运行测试配置后,项目按预期写入 DynamoDb。我还可以在 CloudWatch 日志中看到,已为 event.body 打印了以下内容,这些是 dynamodb.put 的参数:

{
    "TableName": "TestTable",
    "Item": {
        "IngameName": "SomeName",
        "Timestamp": "Fri Oct 09 2020 12:26:12 GMT+0100 (British Summer Time)",
    }
}

因此,当 运行从测试配置中启用 Lambda 函数时,一切正常。但是,当我通过 API 网关调用时,出现以下错误(我将其缩短了一点):

 "MultipleValidationErrors: There were 2 validation errors:",
        "* MissingRequiredParameter: Missing required key 'TableName' in params",
        "* MissingRequiredParameter: Missing required key 'Item' in params"

这是在抱怨缺少 TableNameItem。但是,event.body 的打印显示与执行测试配置时完全相同的输出:

{
    "TableName": "TestTable",
    "Item": {
        "IngameName": "SomeName",
        "Timestamp": "Fri Oct 09 2020 12:26:12 GMT+0100 (British Summer Time)",
    }
}

为什么在通过 API 网关调用时抱怨缺少所需的密钥,但在 运行 测试配置时工作正常,当 dynamodb.put 的参数相同时?

虽然 event.body 的内容看起来正确,但它是一个字符串,这不是 put 操作所期望的。 put 操作需要一个映射。你可以尝试这样的事情:

let requestBody = JSON.parse(event.body)
console.log(requestBody.TableName)

我不知道您的应用程序是如何设置的,但请注意将请求正文的内容直接传递给 put 操作。如果此功能公开,可能会产生不良后果。例如,调用者可以决定将请求发送到另一个 table 名称,向您的 table 引入新属性等。相反,考虑从请求正文中解析参数并将它们传递到 put 手动操作。

const AWS = require('aws-sdk');

const dynamodb = new AWS.DynamoDB.DocumentClient({region: 'eu-west-1'});

exports.handler = async (event) => {
    let requestBody = JSON.parse(event.body)
    console.log("event.body contents", event.body);
    console.log("Inserting into DynamoDb...");
    await dynamodb.put(
        {
            "TableName": "TestTable",
            "Item": {
                "IngameName": requestBody.IngameName,
                "Timestamp": requestBody.Timestamp,
            }
        }
    ).promise();
    return {
        statusCode: 200,
        body: JSON.stringify({message: 'Success'})
    };

};