我一直在尝试为错误响应状态注入自定义标头(并且失败)。
我使用了一个非常简单的lambda
"$input.path('$.errorMessage')"
在api网关中,我完成了以下操作:
设置CORS以包含x-test
responsetemplate = method.response.header.x-test = integration.response.body.x-test
responseparameter包括:
'.*statusCode.*?400.*'
另外,我使用method.response.header.x-test = integration.response.body
事实证明这是空的。
所以我决定退一步看看如果我这样做会发生什么:
{"x-test":"{\"errorMessage\":\"{\\\"name\\\":\\\"error\\\",\\\"message\\\":\\\"I am a failure\\\",\\\"statusCode\\\":400,\\\"x-test\\\":\\\"foo\\\"}\"}"}
我发现我得到了errorMessage的字符串化响应。
"$util.parseJson($input.path('$.errorMessage'))"
所以我决定通过执行以下操作来更改responsetemplate以强制它为json:
responsetemplate = {"x-test":"{\"errorMessage\":\"{\\\"name\\\":\\\"error\\\",\\\"message\\\":\\\"I am a failure\\\",\\\"statusCode\\\":400,\\\"x-test\\\":\\\"foo\\\"}\"}"}
我仍然得到字符串化的回复:
rsGetElementAt_type()
我的猜测是它没有按预期变换,只是为了最终输出。
那么你如何获取一个值并将其推入标题?
谢谢, 凯利
答案 0 :(得分:1)
我认为这更多是关于Lambda和APIGateway所施加的限制的设计选择。我会尽力说出自己的想法。
首先,在Lambda中,回调(错误,结果)函数可以将错误 string 作为第一个参数,或者对象作为结果回应。如果你想传递一个简单的错误信息,你肯定可以这样做。但是,在您的情况下,当您尝试传递整个错误对象时,选择第二个选项显然是一个更好的解决方案(与字符串化对象并再次将其解析为对象相反)。因此,Lambda函数的最后一行应为:
callback(null, error);
是的,在这种情况下,如果您在Lambda中测试您的函数,输出结果将不再是红色并将其标记为错误,但这不重要,因为您可以在APIGateway中格式化标题和响应
现在你需要在APIGateway中进行设置,你需要在其中使用Lambda传递的对象。
在方法响应中,您需要添加要包含在特定状态代码的响应中的标头,在您的情况下为 x-test 。 (如果您希望API返回不同的状态代码,您也可以在此面板中配置它。)
然后转到集成响应,在相同的状态代码下,您会看到添加的标头可用。根据AWS的this文档,您可以使用integration.response.body.JSONPath_EXPRESSION
来分配标头值(这是您应该在Lambda中返回对象而不是字符串的另一个原因,因为没有正式的API来解析对象来自在这个阶段的字符串)。这次,当您的Lambda传递对象时, x-test 标头的值为:
integration.response.body['x-test']
注意:为了在APIGateway中设置不同的状态代码,您应该在响应正文中留下一些可区分的数据字段(您的statusCode:400应该可以正常工作),这样您就可以使用RegEx将这些字段与特定的状态代码匹配。
所以......上面没有成功的消息。我发现这个blog虽然谈论错误处理设计模式。显然他们建议的只是在出现错误时映射状态代码,在这种情况下不应传递任何正文(只有errorMessage),因为浏览器无论如何都不关心200以外的状态代码的响应体。 / p>
我想毕竟,在Lambda将对象传递给APIGateway的同时,不可能同时自定义状态代码和标题?
答案 1 :(得分:0)
这是因为您正在对来自Lambda函数的错误对象进行字符串化。 API Gateway尝试解析JSON-Path表达式,并且无法在字符串中评估“x-test”。如果你返回一个对象而不是一个字符串,这应该可以。
您可能需要考虑使用proxy integrations,它允许您直接从Lambda函数控制标题和状态。
更新:我已经撰写了一篇关于此主题的博文,其中包含示例代码@ https://rpgreen.wordpress.com/2017/01/25/how-to-send-response-headers-for-aws-lambda-function-exceptions-in-api-gateway/