使用 AWS API Gateway 和 Java 处理错误响应状态代码/实体
Posted
技术标签:
【中文标题】使用 AWS API Gateway 和 Java 处理错误响应状态代码/实体【英文标题】:Handling error response status code/entity with AWS API Gateway and Java 【发布时间】:2016-05-10 10:15:43 【问题描述】:我是 AWS API Gateway 的新手,我将它与 AWS Lambda (Java) 一起使用。 显然,更改响应状态代码(更改为 4xx、5xx 等)的唯一方法是返回一个必须与资源的集成响应部分中的 Lambda 错误正则表达式匹配的字符串,或者抛出一个也应该包含与正则表达式匹配的消息,对吗?
但是如果我只能返回一个字符串,我该如何为响应实体提供更多详细信息? 以下是我的 RESTful API 用于返回的内容以及相应的错误状态代码:
"code": "123",
"message": "Invalid email address",
"path": "/email"
code 属性对调试或国际化 (i18n) 很有用,path 是要更正的字段。 有时我将它包装在一个“错误”JSON 对象中,有时我返回一个验证错误列表而不是只有 1 个错误,等等。我根据项目规范对其进行自定义。
如何使用 API Gateway 生成这样的响应实体? 谢谢。
编辑:感谢 kennbrodhagen 的建议,这就是我最终要做的事情:
1. 我将我的错误对象字符串化(使用 Jackson ObjectMapper
)
2. 我抛出了一个RuntimeException
并带有字符串化错误作为消息
在集成响应中:
3. 我将我的错误的某些属性用于 Lambda 错误正则表达式
4. 我映射了这个模板
"error": $input.path('$.errorMessage')
那么API响应(如果发生错误)就变成了
"error": "code": "123", ...
目前非常基本,但比仅在响应中获取字符串要好。
【问题讨论】:
你能返回像 4XX 或 5XX 这样的 HTTP 状态吗?我正在为 Java 和 200 以外的状态代码而苦苦挣扎。如果您有时间,请在此处查看我的问题 ***.com/questions/45200322/…。谢谢! 【参考方案1】:我知道您正在使用 Java,但我更熟悉 node,因此我更容易以这种方式进行原型设计。希望它会翻译过来没有太多麻烦。
这是我在 node.js 中创建的原型函数。目标是将 err 对象作为错误中的 JSON 响应正文返回。 status 属性将用于映射到相应的 HTTP 状态。
exports.handler = function(event, context)
var response =
status: 400,
message: "Error details",
path: "/x"
context.fail(JSON.stringify(response));
;
要使用 status 属性值映射到 HTTP 400,然后将整个结构作为 JSON 响应返回,请执行以下操作:
在 Lambda 中,当您将错误传递给 context.done 或 context.fail 时,对其调用 JSON.stringify() 以将其转换为 JSON 字符串。由于您使用的是 Java,我假设您会找到一种不同的方法将错误转换为等效的 JSON 字符串。
在 API Gateway 集成响应中,将映射设置为使用正则表达式,该表达式将匹配包含 JSON 格式的状态代码的属性。在下面的示例中,我使用 .*"status":400.* 来匹配 status 属性。请注意,我将代码作为数字发送,因此如果您想使用字符串,则必须在正则表达式中添加引号。另请注意,将 .* 放在正则表达式的开头和结尾很重要,这样它将匹配子字符串。
在 API Gateway 集成响应中设置一个 application/json Content-Type 和一个如下所示的映射模板:
$input.path('$.errorMessage')
Lambda 将您传递给 done/fail 的内容并在其上调用 toString()。然后,它将该字符串分配为它发送到 API Gateway 的 JSON 响应中的 errorMessage 属性的值。
接下来,API Gateway 将正则表达式应用于 errorMessage 属性的值。
最后,API Gateway 针对 Lambda 响应字符串执行您的映射模板。映射模板从 errorMessage 中提取值并将其呈现为响应正文。
要让 API Gateway 返回多个不同的状态结果,您需要为每个结果设置单独的集成响应映射。您可以将相同的模板复制/粘贴到每个模板中。
【讨论】:
你的回答启发了我,我会用我最终做的事情来编辑我的问题。希望 AWS 将来会提供一种不那么“肮脏”的方式;-) 我更新了我的回复以解决一些问题并添加更多细节。【参考方案2】:显然,更改响应状态代码(更改为 4xx、5xx 等)的唯一方法是返回一个必须与资源的集成响应部分中的 Lambda 错误正则表达式匹配的字符串,或者抛出一个异常应该包含与正则表达式匹配的消息,对吗?
正确。
在目标响应中,您可以配置映射模板,这些模板可以访问来自 Lambda 的响应的任何其他部分以及上下文变量,这些内容在此处记录:http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html
因此您可以在“/email”下的 400 响应上设置映射模板
"code": "123",
"message": "Invalid email address",
"path": "$context.resourcePath"
或者类似的东西。这将是为您的 Lambda 错误 -> 状态代码映射设置自定义响应正文的唯一方法。
【讨论】:
嗯,我的“path”属性不是资源路径,它是无效字段,如果密码对资源“/register”的调用无效,它可能是“/password”例如。如果您熟悉它,则与 Spring MVC 表单验证相同,它们使用“路径”一词来定义表单中的哪些字段不正确。此外,相同的错误状态代码可能会链接到 JSON 实体中的不同“代码”值。所以这些属性必须以某种方式从 Lambda 处理程序传递到 API Gateway...以上是关于使用 AWS API Gateway 和 Java 处理错误响应状态代码/实体的主要内容,如果未能解决你的问题,请参考以下文章
Google Cloud Api Gateway 是不是提供请求签名和验证 sdk,例如使用 Signature 4 签署 AWS API Gateway 请求?
AWS Lambda 和 Gateway API - 使用 cloudformation 的蓝/绿部署