Aws lambda AWS抱怨一个参数的类型是错误的,而事实并非如此

Aws lambda AWS抱怨一个参数的类型是错误的,而事实并非如此,aws-lambda,amazon-dynamodb,Aws Lambda,Amazon Dynamodb,我是AWS的新手。像新的三天。我在Amazon的一个教程中找到了与DynamoDB表交互的lambda函数的代码。该示例仅为GET请求提供了测试JSON,这将导致数据库中的项目列表,但代码本身支持PUT、POST和DELETE,用于表中的完整CRUD 因此,我创建了一个名为“Users”的DynamoDB表,其中有一个分区键CompanyId,它是一个字符串,还有一个排序键Email,它也是一个字符串。 然后,我创建了一个lambda函数,并添加了教程中的代码: console.log('Lo

我是AWS的新手。像新的三天。我在Amazon的一个教程中找到了与DynamoDB表交互的lambda函数的代码。该示例仅为GET请求提供了测试JSON,这将导致数据库中的项目列表,但代码本身支持PUT、POST和DELETE,用于表中的完整CRUD

因此,我创建了一个名为“Users”的DynamoDB表,其中有一个分区键CompanyId,它是一个字符串,还有一个排序键Email,它也是一个字符串。

然后,我创建了一个lambda函数,并添加了教程中的代码:

console.log('Loading function');

const doc = require('dynamodb-doc');

const dynamo = new doc.DynamoDB();

/**
 * Demonstrates a simple HTTP endpoint using API Gateway. You have full
 * access to the request and response payload, including headers and
 * status code.
 *
 * To scan a DynamoDB table, make a GET request with the TableName as a
 * query string parameter. To put, update, or delete an item, make a POST,
 * PUT, or DELETE request respectively, passing in the payload to the
 * DynamoDB API as a JSON body.
 */
exports.handler = (event, context, callback) => {
    console.log('Received event:', JSON.stringify(event, null, 2));

    const done = (err, res) => callback(null, {
        statusCode: err ? '400' : '200',
        body: err ? err.message : JSON.stringify(res),
        headers: {
            'Content-Type': 'application/json',
        },
    });

    switch (event.httpMethod) {
        case 'DELETE':
            dynamo.deleteItem(JSON.parse(event.body), done);
            break;
        case 'GET':
            dynamo.scan({ TableName: event.queryStringParameters.TableName }, done);
            break;
        case 'POST':
            console.log(event.body);
            dynamo.putItem(JSON.parse(event.body), done);
            break;
        case 'PUT':
            dynamo.updateItem(JSON.parse(event.body), done);
            break;
        default:
            done(new Error(`Unsupported method "${event.httpMethod}"`));
    }
};
在测试GET代码之后(由于我的表是空的,所以得到了一个长度为0的项目列表),我决定创建一个将向数据库添加一个项目的测试。我创建了一个名为PostTest的测试事件,它包含以下测试内容:

{
  "httpMethod": "POST",
  "body": "{\"Item\": {\"CompanyId\": {\"S\": \"test-company-id\"},\"FirstName\": {\"S\": \"John\"}, \"LastName\": {\"S\": \"Doe\"}, \"Email\": {\"S\": \"john.doe@gmail.com\"}, \"Password\": {\"S\": \"password\"}}, \"TableName\": \"Users\"}"
}
我想指出一个事实,CompanyId被设置为“S”,或者换句话说,设置为string类型

当我运行测试时,我得到以下响应:

{
  "statusCode": "400",
  "body": "One or more parameter values were invalid: Type mismatch for key CompanyId expected: S actual: M",
  "headers": {
    "Content-Type": "application/json"
  }
}
Type mismatch for key CompanyId expected: S actual: M
日志的内容是:

START RequestId: 294a7414-cde5-11e8-a7bd-bd58483e1612 Version: $LATEST
2018-10-12T06:07:56.232Z    294a7414-cde5-11e8-a7bd-bd58483e1612    Received event: {
  "httpMethod": "POST",
  "body": "{\"Item\": {\"CompanyId\": {\"S\": \"test-company-id\"},\"FirstName\": {\"S\": \"John\"}, \"LastName\": {\"S\": \"Doe\"}, \"Email\": {\"S\": \"john.doe@gmail.com\"}, \"Password\": {\"S\": \"password\"}}, \"TableName\": \"Users\"}"
}
2018-10-12T06:07:56.232Z    294a7414-cde5-11e8-a7bd-bd58483e1612    {"Item": {"CompanyId": {"S": "test-company-id"},"FirstName": {"S": "John"}, "LastName": {"S": "Doe"}, "Email": {"S": "john.doe@gmail.com"}, "Password": {"S": "password"}}, "TableName": "Users"}
END RequestId: 294a7414-cde5-11e8-a7bd-bd58483e1612
REPORT RequestId: 294a7414-cde5-11e8-a7bd-bd58483e1612  Duration: 173.04 ms Billed Duration: 200 ms     Memory Size: 512 MB Max Memory Used: 30 MB
我对答复中的错误感到困惑:

{
  "statusCode": "400",
  "body": "One or more parameter values were invalid: Type mismatch for key CompanyId expected: S actual: M",
  "headers": {
    "Content-Type": "application/json"
  }
}
Type mismatch for key CompanyId expected: S actual: M
如果查看日志,则在请求正文中,CompanyId设置为“S”。“M”来自哪里?我做错了什么


不用说,我的表中没有添加任何项目

我不知道dynamodb doc的背后是什么,但我对aws sdk有类似的问题

给定
const AWS=require('AWS-sdk')
您可能有两个连接器。例如:

  • const DDB=new AWS.DynamoDB()
  • const DC=new AWS.DynamoDB.DocumentClient()
使用
DDB
连接时,必须使用类型按您的方式格式化项目

使用DocumentClient(
DC
)时,类型是推断的,因此您不必显式提供类型。试着这样做:

{
  "httpMethod": "POST",
  "body": "{\"Item\": {\"CompanyId\": \"test-company-id\",\"FirstName\": \"John\", \"LastName\": \"Doe\", \"Email\": \"john.doe@gmail.com\", \"Password\":  \"password\"}, \"TableName\": \"Users\"}"
}

使用
DC
,CompanyId被正确地推断为映射:
{\'S\':\'testcompanyid\'}
。垃圾进,垃圾出。:)

科斯汀,谢谢你。这两个建议都奏效了。我读了DocumentClient,我喜欢它。我知道我可能会在某个时候遇到它的局限性,但我认为现在它能满足我的需要。不客气,提比。我使用DocumentClient已经有一段时间了,我对它非常满意。我只在使用StringSet时遇到了一些问题,使用
dynamodb local
和AWS进行测试时存在一些差异。需要时带着问题回来。。。同时使用文档客户端,它更简单;)