向 AWS Lambda 发送带有正文的请求

Posted

技术标签:

【中文标题】向 AWS Lambda 发送带有正文的请求【英文标题】:Send a request with a body to AWS Lambda 【发布时间】:2019-06-05 07:25:03 【问题描述】:

我上传了一个 AWS Lambda 函数,其中 lambda_handler 如下所示:

import json
def lambda_handler(event, context):

    print(event)

    return 
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!'),
        'event': event
    

问题一:返回event

当我使用 Lambda 管理控制台对其进行测试时,我可以创建一个带有参数的测试事件,这些参数也返回完全相同的格式并且一切正常:


  "key1": "value1",
  "key2": "value2",
  "key3": "value3"

但是,当我使用 Postman 时,我会得到完全不同的东西,这会返回给我:


    "message": "Internal server error"

我怀疑是因为event 看起来更像:

'resource': '/hello', 'path': '/hello', 'httpMethod': 'GET', 'headers': 'Accept': '*/*', ... etc

问题2:在body中添加json参数会报错

当我尝试在 Postman 中添加 body > raw > JSON(application/JSON) 上面的键时,我得到了错误:

ERROR: The request could not be satisfied

问题

我有两个问题:

如何在正文中传递参数并能够使用事件或上下文在 AWS lambda 中捕获它? 如何正确返回事件?

【问题讨论】:

您是否使用Content-Type:application/json 传递标题? 在正文中我指定了对吗? 不在正文中,而是作为标题。首先在 Postman 上进行测试。此外,您必须为此使用 API 链接? API 链接可能还需要某种身份验证。请分享您在 Postman 上获得的状态码。对于内部服务器错误,很可能是 500。 当你在正文中发送信息时,你应该做一个POST 请求。如果您尝试执行GET 请求,则正文没有任何意义。这个链接可能有帮助docs.aws.amazon.com/apigateway/latest/developerguide/… 【参考方案1】:

假设您已将 Lambda 设置为 AWS API Gateway 中的代理集成。如果你想附加查询字符串参数并且没有正文,那么你的方法类型应该是 GET。

您将在 Lambda 中收到请求 /GET your-path/?myKey1=value1&myKey2=value2 的事件应该类似于:


    "resource": "",
    "path": "/your-path",
    "httpMethod": "GET",
    "headers": 
    ,
    "queryStringParameters": 
      "myKey1": "value1",
      "myKey2": "value2"
    ,
    "pathParameters": 
    ,        
    "body": ""
  

您可以在queryStringParameters 属性中访问查询字符串参数。

如果您使用 Postman 发送请求并附加正文,那么您的 Lambda 集成类型应该是 POST/PUT。您在 Postman 请求正文中添加的数据将在 event["body"] 中提供。

如果您直接在控制台中测试 Lambda,那么最后一件事将在您放入正文时收到事件。您需要根据集成方法类型来格式化您的事件。如果是 POST/PUT 则:


 "body": 
   "someValue": ..
 

如果是 GET 则:


 "queryStringParameters": 
    "myKey1": "value1",
    "myKey2": "value2"
  

【讨论】:

谢谢。试过了,没用,又是邮递员的内部服务器错误 Cloudwatch 日志显示一切正常,没有错误...所以我猜是返回事件。 您能否确认您在原始帖子中附加的 Python 代码是您仍在使用的代码?如果是这样,您需要从响应中删除 event 属性。您能否确认您已在网关中设置代理集成?另请确认集成方法类型并请求您发布到端点 无代理集成。但我觉得奇怪的是,在日志中我没有看到事件中的“正文”,只是标题。这怎么可能?【参考方案2】:

在@Althar Khan 的帮助下解决了这个问题。

AWS Lambda 的 API Gateway 显然只接受某些属性:

...
return 
    "statusCode": 200,
    "headers": 
        "my_header": "my_value"
    ,
    "body": JSON.stringify(responseBody),
    "isBase64Encoded": false
;

在此响应中,有四个字段:statusCode、headers、body 和 isBase64Encoded。

在此示例中,函数的响应采用 API Gateway 期望的格式。如需更多信息,请参阅Output Format of a Lambda Function for Proxy Integration。

【讨论】:

谢谢。我也遇到了同样的问题。

以上是关于向 AWS Lambda 发送带有正文的请求的主要内容,如果未能解决你的问题,请参考以下文章

使用 webargs 验证 AWS lambda 中的查询字符串参数和请求正文

AWS Lambda 错误:当 url 参数包含 JSON 数组时,“无法将请求正文解析为 json”

如何使用 AWS Lambda 向邮递员 POST 请求

Python3 AWS Lambda-向需要VPN的域发出发布请求

如何在 swagger 上分析请求(带有查询)并发送不同的响应正文?

如何将签名的 HTTP 请求从 AWS Lambda 发送到 AppSync GraphQL?