【问题标题】:Serving different media types in AWS Lambda with Java/Scala使用 Java/Scala 在 AWS Lambda 中提供不同的媒体类型
【发布时间】:2019-01-30 00:16:54
【问题描述】:

在为 AWS Lambda(Java/Scala)编写函数时,处理函数可以具有不同的签名之一:

// Raw input / output
def handleRequest(is: InputStream): OutputStream = ???

// Using the AWS dependency
def handleRequest(input: APIGatewayProxyRequestEvent, context: Context): APIGatewayProxyResponseEvent = ???

这是我所知道的至少两个可能的签名。也许还有更多。

不同之处在于第一个是原始响应,需要由 API 网关使用手动配置的媒体类型和响应代码等属性打包到 REST 响应中。

第二个响应似乎利用了 Lambda 代理集成,并将从 APIGatewayProxyResponse 中提取所有配置。

现在回答我的问题:

APIGatewayProxyResponse 的字段 body 的类型为 String。 在我看来,这个 POJO 在发送到 API 网关之前被序列化为 JSON。 这将导致无法提供图像或 PDF 文件等二进制数据。

原始的OutputStream 不能携带有关标头等的信息(或者可以吗?),这意味着我不能提供多种不同的媒体类型。

当然,我可以将图像转换为 Base64。但这远非最佳。

有没有一种方法可以在单个 AWS Lambda 处理程序中提供不同的(二进制和非二进制)媒体类型(具有正确的标头等)?我必须如何为此配置 API 网关?

【问题讨论】:

  • 您可以将用户输出流以 json 格式发送发送完整响应(包括标头)。 JSONObject 响应 = 新 JSONObject(); response.put("headers", headerJsonObject); response.put("body", responseBody.toString());OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8");
  • @Kaushal 好的,但我很确定我不会被允许只将二进制垃圾写入 JSON。
  • 对于二进制,不要发送 json 响应。根据情况在输出流中发送 json 或二进制。 API 网关 api 可以根据其配置来处理响应。示例docs.aws.amazon.com/apigateway/latest/developerguide/…
  • @Kaushal 我的问题是关于可以both 的单个处理程序。

标签: scala amazon-web-services aws-lambda


【解决方案1】:

注意:此答案基于阅读文档。我没有在实践中尝试过,所以它可能不起作用。

如果您打开文档的 "Output Format of a Lambda Function for Proxy Integration" 部分,您可能会看到 isBase64Encoded 字段和以下文本:

输出body 被编组到前端作为方法响应负载。如果body 是二进制blob,则可以将其编码为Base64 编码字符串并将isBase64Encoded 设置为true。否则,您可以将其设置为 false 或不指定。

如果您打开APIGatewayProxyResponse in the .Net library,您可以在那里看到IsBase64Encoded 属性。看起来只是没有公开此字段的 Java API。但是所有其余的基础设施都应该支持它。您可能还会看到在某些时候将类似的字段添加到 APIGatewayProxyRequestEvent.java,但未添加到 APIGatewayProxyResponse。所以我认为以下解决方法应该有效:使用isBase64Encoded 字段创建您自己的APIGatewayProxyResponseEvent 类并使用它。或者只是从标准com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent 扩展并在您的子类中添加此字段。我希望如果您符合命名约定,它应该可以工作。毕竟它应该被编组为 JSON。

【讨论】:

  • @MarkusAppel,阅读文档我希望如果您设置 isBase64Encoded = true 并配置了 binaryMediaTypes,代理将解码 base64 并将其作为原始数据传递给客户端。我还没有尝试过。另见Support Binary Payloads in API Gateway
  • 这听起来很合理。太糟糕了,你仍然需要 base64 - 编码,没有它会好得多。
  • @MarkusAppel,我建议您仅在尝试后将其标记为已接受的答案并确保它在实践中有效。到目前为止,这只是一个有根据的猜测。
  • 您的回答已经很有帮助,并且可以根据新发现进行更改。反正我没有标记它。
  • @MarkusAppel,SO 同时是一个回答平台和一个知识库,有时这些功能是不一致的。如果它有效,请返回并将其标记为已接受的答案,以便人们知道它有效。如果没有,请返回并发表评论说它仍然不起作用。
猜你喜欢
  • 2012-05-23
  • 1970-01-01
  • 2020-09-07
  • 1970-01-01
  • 2019-11-06
  • 2016-06-06
  • 2020-04-21
  • 1970-01-01
相关资源
最近更新 更多