在 AWS Lambda 函数中从 S3 获取对象并发送到 Api Gateway
Posted
技术标签:
【中文标题】在 AWS Lambda 函数中从 S3 获取对象并发送到 Api Gateway【英文标题】:Get object from S3 in AWS Lambda function and send to Api Gateway 【发布时间】:2015-11-19 16:45:39 【问题描述】:我正在尝试从存储桶中获取 .jpg 文件并将其发送回 api 网关。当我看到正在记录的内容时,我相信我的设置是正确的。它可以很好地从 s3 中获取文件,而 gm 是 graphicsmagick 库。不知道我是否正确使用它。
在 lambda 函数中我这样做(很多代码来自 aws 示例):
async.waterfall([
function download(next)
console.log(srcKey);
console.log(srcBucket);
// Download the image from S3 into a buffer.
s3.getObject(
Bucket: srcBucket,
Key: srcKey
,
next);
,
function transform(response, next)
console.log(response);
next(null, 'image/jpeg', gm(response.Body).quality(85));
,
function sendData(contentType, data, next)
console.log(contentType);
console.log(data);
imageBuffer = data.sourceBuffer;
context.succeed(imageBuffer);
]
);
响应头的内容长度为:85948,这似乎不正确,因为原始文件只有 36kb。有谁知道我做错了什么?
【问题讨论】:
图像可能会因处理而增大,这并非不可想象,但似乎不太可能。实际的响应正文是什么样的,例如,保存然后在文本/十六进制编辑器中查看? 哈基本上实现了完全相同的东西,只是在几个小时后终于偶然发现了这个问答:'( 现在有可能 - aws.amazon.com/blogs/compute/… 【参考方案1】:您可以轻松实现 Get Image API Gateway Lambda S3 集成。
在 lambda 中,而不是 json,返回图像的 base64 字符串表示(buffer.toString('base64')
),强制 API Gateway 将字符串转换为二进制并添加特定的Content-Type
(因此您不需要使用它们有限的二进制支持强制您发送特定的 Accept 标头)。
在 AWS 控制台中,进入 API Gateway,然后进入相关方法并更新设置:
集成请求
取消选中:使用 Lambda 代理集成方法响应
添加响应 -> HTTP 状态:200 添加标题:内容类型集成响应 -> 标头映射 -> 响应标头 -> 内容类型
映射值:'image/jpeg'(单引号问题)从命令行,运行以下命令强制将字符串转换为二进制。 首先,从 API Gateway 检索 rest-api-id 和 resource-id。 然后,在 CLI 中运行(将 rest-api-id 和 resource-id 替换为您自己的):
aws apigateway put-integration-response --rest-api-id <rest-api-id> --resource-id <resource-id> --http-method GET --status-code 200 --content-handling CONVERT_TO_BINARY
【讨论】:
有没有办法通过 Lambda 代理集成来做到这一点?当我取消选中使用 Lambda 代理集成时,我的查询字符串不再传递给 Lambda 函数。【参考方案2】:当您将API Gateway
与Lambda
一起使用时,您不应使用API Gateway
来传回二进制内容。 API Gateway
和 Lambda
设置为响应 XML/JSON
数据。详细了解here 的原因和方式。
尝试更改您的回调链,以便将修改后的图像上传回S3
。上传成功后,发回目标对象的URI
,并将客户端重定向到它。
【讨论】:
我在文档中没有看到任何排除这一点的内容。你可以说得更详细点吗?服务的预期用途并不总是排除替代应用程序,并且 OP 的应用程序似乎是合法的。通过 API Gateway 返回二进制内容是否存在实际限制? 简单地说:context.done(...)
在你的缓冲区上调用.toString()
。 AWS Gateway
数据管道围绕 Integration Request/Response
旋转,并且始终是 JSON/XML。
此外,通过 API 本身传递内容在 AWS 环境中是一种不好的做法。 API Gateway
和 Lambda
的超时时间都相对较短。 API Gateway
有 30 秒,Lambda
有 60 秒。
好的,感谢您的帮助。我会进一步研究它,但你所说的将修改后的图像存储回 s3 确实有道理。以上是关于在 AWS Lambda 函数中从 S3 获取对象并发送到 Api Gateway的主要内容,如果未能解决你的问题,请参考以下文章
AWS Lambda 返回权限被拒绝尝试从 S3 存储桶获取对象
在不同账户的 Lambda 中从 AWS Athena 查询 S3 文件时访问被拒绝
如何使用 lambda 函数从 AWS s3 获取文本文件的内容?