我们正在尝试将 zip 微服务从 Nodejs Express 中的常规应用程序迁移到与 AWS Lambda 集成的 AWS API Gateway。
我们当前的应用程序向我们的 API 发送请求,获取附件列表,然后访问这些附件并将其内容以 zip 存档的形式返回给用户。它看起来像这样:
module.exports = function requestHandler(req, res) {
//...
//irrelevant code
//...
return getFileList(params, token).then(function(fileList) {
const filename = `attachments_${params.id}`;
res.set('Content-Disposition', `attachment; filename=${filename}.zip`);
streamFiles(fileList, filename).pipe(res); <-- here magic happens
}, function(error) {
errors[error](req, res);
});
};
除了必须从 Lambda 函数流式传输内容的部分之外,我已成功完成所有操作。
我认为可能的解决方案之一是使用 aws-serverless-express,但我想要一个更优雅的解决方案。
有人有什么想法吗?是否有可能从 Lambda 中流出?
不幸的是,lambda 不支持流作为事件或返回值。 (很难在文档中找到明确提及的内容,除非注意工作文档中如何描述调用和上下文/回调)。
在您的示例中,您必须等待
streamFiles
,然后返回完成的结果。
(
aws-serverless-express
在这里没有帮助,如果您检查代码,他们会等待管道完成后再返回:https://github.com/awslabs/aws-serverless-express/blob/master/src/index.html js#L68)
n.b.这里有一个细微差别,许多语言 SDK 支持流式传输请求/响应,但这意味着连接到流传输,例如从 lambda 下载完整响应的流,而不是侦听从 lambda 发出的流。
遇到了同样的问题,现在确定如何直接通过本机 lambda + API 网关进行流/管道...但在技术上是可行的。
我们使用了
Serverless Framework
并且能够通过此入门套件使用 XX.pipe(res)
(https://github.com/serverless/examples/tree/v3/aws-node-express-dynamodb-api)
有趣的是,这只是包装了本机 lambda + API 网关,因此从技术上讲这是可能的,因为他们已经做到了。
祝你好运
自 2023 年 4 月起,可以从 NodeJS Lambda 函数流式传输结果(请参阅:introducing-aws-lambda-response-streaming)。
但是,请记住,此处不支持开箱即用地使用 API 网关作为函数的入口点。如果您想扩展调用,您将需要使用 HTTP 代理或创建 CloudFront 发行版。
API Gateway 和 Lambda 与 Application Load Balancer 的目标集成都不支持分块传输编码。因此,它不支持更快的 TTFB 流式响应。但是,您可以将响应流与 API Gateway 结合使用来返回更大的负载响应,最高可达 API Gateway 的 10 MB 限制。要实现此目的,您必须在 API 网关和 Lambda 函数 URL 之间配置 HTTP_PROXY 集成,而不是使用 LAMBDA_PROXY 集成。
您可以通过设置一个简单的处理程序来进行测试,如下所示:
exports.handler = awslambda.streamifyResponse(async (event, responseStream, context) => {
responseStream.setContentType("text/plain");
for (let i = 0; i < 5; i++) {
responseStream.write(`Message ${i}\n`);
await new Promise(resolve => setTimeout(resolve, 1000));
}
responseStream.end();
});
然后通过函数 URL 调用该函数并观察消息流。