我有Lambda,它执行几次对DynamoDB的调用,创建一个大的字符串化JSON对象作为响应,并通过API传递给客户端应用程序。当然,API有“内容编码启用”选项集,所有数据都以压缩的形式在互联网上传递。
问题是Lambda响应本身没有被压缩,并且达到了6MB的响应限制。是否有可能压缩Lambda响应,然后在客户端以某种自然的方式解压它?
我检查了node.js库,如JSZip和ADM Zip,并且惊讶地发现,尽管它们允许在内存中输出解压缩数据,但它们不允许字符串、缓冲区或smth之类的内存中输入,而只允许文件。Lambda已经有几个与处理文件相关的限制和惊喜,所以我想避免以下冗余的工作流:
environment
有没有更自然的方法来处理这个问题?
发布于 2021-07-21 12:51:56
我遵循了下一个方法。后端:
const { deflate, unzip } = require("zlib");
const { promisify } = require("util");
const asyncDeflate = promisify(deflate);
async zip(object) {
return (await asyncDeflate(JSON.stringify(object))).toString("base64");`
}
前端:
import * as pako from "pako";
export function unzip(base64str: string) {
const strData = atob(base64str);
// Convert binary string to character-number array
const charData = strData.split("").map((x) => { return x.charCodeAt(0); });
// Turn number array into byte-array
const binData = new Uint8Array(charData);
return JSON.parse(pako.inflate(binData, { to: "string" }));
}
因此,这与最近的答案相当相似。
发布于 2021-07-02 19:41:42
虽然我同意使用分页或S3更适合于大量数据,但您可以压缩从Lambda函数返回的响应,以避免在需要时达到6MB的限制。
不幸的是,虽然API网关现在支持像gzip这样的内容编码,但我的理解是,在API压缩之前,Lambda函数的响应仍然需要低于6MB的限制。我不能百分之百地肯定这一点,所以如果我错了,请有人纠正我。
好消息是,node.js标准库现在已经通过zlib模块内置了对gzip的支持。我用这个来压缩刚刚超过6MB的响应,并将大小减少了大约78%。这样做的缺点是,我必须在我的角度客户端应用程序中手动解压缩数据(为此我使用了pako库)。
下面的内容对我很有用(打字稿4+ node.js 12):
import { APIGatewayEvent, APIGatewayProxyResult } from 'aws-lambda';
import { gzip } from 'zlib';
export const handler = async (event: APIGatewayEvent): Promise<APIGatewayProxyResult> => {
const response = { some: 'data' };
const gzippedResponse = await gzipString(JSON.stringify(response));
return {
statusCode: 200,
body: JSON.stringify({ data: gzippedResponse.toString('base64') }),
};
};
const gzipString = async (input: string): Promise<Buffer> => {
const buffer = Buffer.from(input);
return new Promise((resolve, reject) => gzip(buffer, (err, data) => {
if (err) {
reject(err);
}
resolve(data);
}));
};
发布于 2020-05-26 15:24:07
有多种方法可以通过稍微改变体系结构来处理这个问题:
https://stackoverflow.com/questions/62025368
复制相似问题