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"
这是在抱怨缺少 TableName
和 Item
。但是,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'})
};
};
我有一个 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"
这是在抱怨缺少 TableName
和 Item
。但是,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'})
};
};