1

使用 AWS,我使用 Python 设置了一个 Lambda 函数作为代理。从 API 网关,我已将 lambda(选中“使用 Lambda 代理集成”复选框)链接到我的 API 网关。一切工作正常,除了 lambda 函数的最大 6mb 大小妨碍了我的大文件成功返回。lambda 打印一条错误消息,指出“响应负载大小超出了允许的最大负载大小。Function.ResponseSizeTooLarge”,API 网关从 lambda 获取此消息并打印“收到的响应。状态 200”、“由于客户函数错误,Lambda 执行失败,状态为 200:响应负载大小超过了允许的最大负载大小”,然后 API 网关会输出 502 并显示消息“内部服务器错误”。

我期望发生的是 API Gateway 会看到此错误消息并自动返回 413 Request Entity Too Large,以便我可以从我的 webapp 对特定错误状态做出反应。

在过去,我已经能够使用 api 网关的集成响应部分来查找此错误消息并覆盖传出状态代码,如下所示:

#set($inputRoot = $input.path('$'))
$input.json("$")
#if($inputRoot.toString().contains("ResponseSizeTooLarge"))
#set($context.responseOverride.status = 413)
#end

不幸的是,因为我使用来自 api 网关的这个 lambda 函数作为 lambda 代理,所以我无法使用集成响应来搜索此特定消息并覆盖传出状态代码。

有没有另一种方法可以让 API Gateway 看到它从 lambda 获得的这 200 实际上有一条错误消息,并且无论如何应该是 413?我能想到的唯一另一种方法是在手动将其返回到 API 网关之前检查 lambda 的有效负载大小,然后在返回之前更改状态代码(如果它太大)。我不想这样做,因为我看到在 python 中获取对象字节大小的唯一方法是导入 sys 并使用:

sys.getsizeof(lambdaResponse)

这似乎只返回了 ~258 的大小,即使它的内容的实际大小比这大得多。我也不想检查每个有效负载的大小,因为它可能会给不太大而无法处理的响应增加不必要的延迟。

4

2 回答 2

1

到目前为止,还没有默认的方法来实现这一点。正如您所说,您能做的最好的事情是检查 lambda 本身的有效负载大小,然后返回/抛出异常。


只是一个建议,如果您的用例要求响应负载超过 lambda 函数的允许限制,我建议将响应负载存储在某个 s3 存储桶中,并将负载的 s3 url 作为响应返回。这样,您的应用程序将随着响应负载的增加而很好地扩展。此外,如果这些响应是可缓存的,您可以轻松地重用相同的 s3Url,只需对应用程序逻辑稍作修改。

于 2020-04-22T20:35:26.653 回答
1

因此,虽然遗憾的是没有默认方法可以从 api 网关处理这种情况,但仍然可以选择在 lambda 函数中处理此错误。在将 lambda 的响应返回到 api 网关之前,我使用了 mango 的建议,并使用以下命令检查了响应的字节大小:

len(json_obj.encode("utf-8"))

如果超过了 lambda 可以返回的限制,我将 response.status 更改为 413 并将正文更改为解释发生了什么的错误消息

于 2020-04-29T14:52:49.337 回答