通过API网关从AWS lambda返回二进制正文和http标头

时间:2018-01-07 13:46:40

标签: amazon-web-services aws-lambda aws-api-gateway

我有一个lambda需要通过api网关(使用lambda集成)返回二进制对象和一些http标头(例如content-type)或重定向到另一个URL。在二进制支持示例(例如https://aws.amazon.com/blogs/compute/binary-support-for-api-integrations-with-amazon-api-gateway/)中,lambda仅返回二进制对象(图像)的(base64)。在我的情况下,我还需要返回一个状态代码和http标头(或类似的东西)。我很难在api网关中使用二进制支持来完成这项工作。

lambda在这个表单上返回一个json:

{
  "statusCode": 200,
  "headers": {
    "content-type": "image/jpeg"
  },
  "body": "/9j/4AAQS...gLDAoKCAwZK",
  "isBase64Encoded": true
}

在集成响应中,我为表单的image / jpeg(等)添加了body映射:

$input.json('$.body')

“内容类型”的标题映射如下:

integration.response.body.headers['content-type']

我尝试了上述的许多变体,但结果始终是

Execution failed due to configuration error: Unable to transform response 

如何将json从lambda转换为可以通过api网关转换为二进制的形式,http头和所有?我可以从api网关获得更多的调试日志记录,以显示更具体的不满意的内容吗?

是否有办法从api网关中获取更多调试日志?

3 个答案:

答案 0 :(得分:1)

我在面对类似问题后最近才开始工作。

就我而言,我错过了两件事:

首先,我需要更改AWS将在"接受"中发送到上游的类型列表。报头"

"x-amazon-apigateway-binary-media-types" : [
  "image/jpeg"
]

其次,我需要将积分响应设置为"转换为二进制(如果需要)":

"contentHandling": "CONVERT_TO_BINARY"

有关详细信息,请参阅this answer,并参见示例配置。

我还发现我没有足够的耐心。每当我部署API时,我都会立即检查,而不是等待几分钟才能传播更改。

答案 1 :(得分:0)

我几天都在努力做同样的事情,但是找不到任何文件来备份它是可能的,而是我找到了这个 https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-payload-encodings-workflow.html

  

将文本有效负载转换为二进制blob时,API Gateway假定>文本数据是Base64编码的字符串,并将二进制数据输出为   Base64解码的blob。如果转换失败,则返回500响应   指示API配置错误。您没有提供映射模板   对于这种转换,尽管您必须启用直通行为   API。

     

将二进制有效负载转换为文本字符串时,API网关始终应用>二进制数据的Base64编码。您可以为其定义映射模板   这样的有效负载,但只能访问映射中的Base64编码的字符串   模板通过$ input.body,如以下示例摘录>所示。映射模板。

这听起来像这样的映射只能以相反的方式进行;我最终做的是只返回Base64Encoded二进制字符串并在头映射中硬编码内容类型和缓存控制;有关完整实施的信息,请参阅我的博文https://mesfinmoges.com/dynamic-image-resizing-using-amazon-s3-aws-lambda-mazon-api-gateway-amazon-cloudfront/

答案 2 :(得分:0)

我厌倦了使用base64编码返回二进制数据,但我无法通过API网关从Lambda函数返回它。

因此,我决定重定向网址。我将方法响应更改为302并添加了“位置”响应标头。我还从Integration Response中删除了响应代码200,选择302作为响应代码并使用integration.response.body.location标头映射Location值。我的Lambda代码以这种格式返回重定向URL的位置:

{"location":"www.google.com/"}

希望这有帮助。