【问题标题】:Unable to send GET request with AWS Lambda & DynamoDB Rest API using serverless无法使用无服务器使用 AWS Lambda 和 DynamoDB Rest API 发送 GET 请求
【发布时间】:2021-01-30 05:27:41
【问题描述】:

我正在创建一个 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)));
};

【问题讨论】:

  • 错误请求是指状态码 400 吗?可能只是您没有正确调用您的 API。错误代码列表 -> w3.org/Protocols/rfc2616/rfc2616-sec10.html
  • 实际上是 403。
  • 确保调用正确的 url。
  • 您能否发布部署命令的输出、serverless.yml 以及您如何在 postman 中调用 API?
  • 设法解决了它并且没有使用无服务器。问题是关于角色和政策以及我发布的参数。

标签: amazon-web-services aws-lambda amazon-dynamodb amazon-cloudfront serverless-framework


【解决方案1】:

我设法做到了,但没有使用无服务器。

我将 Lambda 函数设置为从 url POST 和 GET 数据。

我认为之前的问题与政策有关。这次在制作 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 标头。

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

Part 1

Part 2

【讨论】:

    【解决方案2】:

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

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

    此页面包含一个示例链接。

    错误列表codes

    【讨论】:

    • 您没有在问题解决方案中添加任何内容。仅发布链接可能会有所帮助,但它们应该作为评论。
    猜你喜欢
    • 2018-12-13
    • 2020-04-15
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-08
    • 1970-01-01
    相关资源
    最近更新 更多