无法使用无服务器通过 AWS Lambda 和 DynamoDB Rest API 发送 GET 请求

问题描述 投票:0回答:3

我正在创建一个 API 来向 DynamoDB 中的表发出 GET 和 POST 请求。

我使用无服务器部署它并接收了每种 API 类型的端点。

但是当用 Postman 测试它时,我收到以下错误:

Bad request. We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner. 
If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation. 

创建表中数据的代码:


const postsTable = process.env.POSTS_TABLE;
// Create a response
function response(statusCode, message) {
    return {
        statusCode: statusCode,
        body: JSON.stringify(message)
    };
}

// Create a post
module.exports.createPost = (event, context, callback) => {
    const reqBody = JSON.parse(event.body);

    if (
        !reqBody.title ||
        reqBody.title.trim() === "" ||
        !reqBody.body ||
        reqBody.body.trim() === ""
    ) {
        return callback(
            null,
            response(400, {
                error:
                    "Post must have a title and body and they must not be empty"
            })
        );
    }

    const post = {
        id: uuidv4(),
        createdAt: new Date().toISOString(),
        userId: 1,
        title: reqBody.title,
        body: reqBody.body
    };

    return db
        .put({
            TableName: postsTable,
            Item: post
        })
        .promise()
        .then(() => {
            callback(null, response(201, post));
        })
        .catch(err => response(null, response(err.statusCode, err)));
};

amazon-web-services aws-lambda amazon-dynamodb amazon-cloudfront serverless-framework
3个回答
1
投票

我设法做到了,但没有使用 Serverless。

我设置了 Lambda 函数来 POST 并从 URL 获取数据。

我认为之前的问题与政策有关。这次在制作 Lambda 函数时我将其设置如下:

我在为新函数创建执行角色时单击“从 AWS 策略模板创建新角色”,然后为策略模板选择“简单微服务权限”。这为与该函数位于同一区域中的所有表的角色添加了基本执行角色策略和低于 DynamoDB 权限:

"Action": [
               "dynamodb:DeleteItem",
               "dynamodb:GetItem",
               "dynamodb:PutItem",
               "dynamodb:Scan",
               "dynamodb:UpdateItem"
           ]

用于 POST 请求的 Lambda 函数

exports.handler = async (event, context) => {
    const ddb = new AWS.DynamoDB({ apiVersion: "2012-10-08" });
    const documentClient = new AWS.DynamoDB.DocumentClient({
        region: "ap-southeast-1"
    });

    let responseBody = "";
    let statusCode = 0;

    const {
        deviceId,
        batteryLevel,
        eventId,
        id,
        location,
        tags,
        time
    } = JSON.parse(event.body);

    const params = {
        TableName: "dashboard",
        Item: {
            batteryLevel: batteryLevel,
            deviceId: deviceId,
            eventId: eventId,
            location: location,
            tags: tags,
            time: time
        }
    };

    try {
        const data = await documentClient.put(params).promise();
        responseBody = JSON.stringify(data);
        statusCode = 201;
    } catch (err) {
        responseBody = "Unable to POST data";
        statusCode = 403;
    }
    const response = {
        statusCode: statusCode,
        headers: {
            myHeader: "test"
        },
        body: responseBody
    };
    return response;
};

其他问题还与 API 的方法执行有关,我需要为请求正文设置自定义模型以匹配我的数据:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": "DashboardInputModel",
  "type": "object",
  "properties": 
  {
  "batteryLevel": {"type": "string"},
  "deviceId": {"type": "string"},
  "eventId": {"type": "string"},
  "id": {"type": "number"},
  "location": {
      "type": "object",
      "properties":{
            "accuracy": {"type": "number"},
            "latitude": {"type": "number"},
            "longitude": {"type": "number"}
      }
  },
  "tags": {
   "type": "array",
      "items": {
        "type": "object",
        "properties": {
      "accelX":{"type": "number"},
      "accelY": {"type": "number"},
      "accelZ": {"type": "number"},
      "createDate": {"type": "string"},
      "dataFormat":{"type": "number"},
      "defaultBackground": {"type": "number"},
      "favorite": {"type": "boolean"},
      "humidity": {"type": "number"},
      "id": {"type": "string"},
      "measurementSequenceNumber": {"type": "number"},
      "movementCounter": {"type": "number"},
      "name": {"type": "string"},
      "pressure": {"type": "number"},
      "rssi": {"type": "number"},
      "temperature": {"type": "number"},
      "txPower":{"type": "number"},
      "updateAt": {"type": "string"},
      "voltage": {"type": "number"}
        }
    }   
  },
  "time": {"type": "string"}
}
}

对于每个操作,我还启用了 CORS 并替换了现有的 CORS 标头。

这两个视频比文档更好地解释了整个过程,我希望它有所帮助。

第 1 部分

第 2 部分


0
投票

我收到了这个确切的错误,发现问题实际上是我通过邮递员发送带有正文的请求。我只需在正文中选择“无”选项并且不发送任何内容,请求就可以正常工作。


-1
投票

错误请求是指状态代码 400 吗?可能只是您没有正确调用 API。

如果您收到 403,那么您需要通过该信息表明您有权访问您尝试获取的资源。您可以通过 AWS docs 了解如何执行此操作。

此页面包含示例链接。

错误列表代码

© www.soinside.com 2019 - 2024. All rights reserved.