API Gateway 集成响应映射:从 Step Function 输出中解析 statusCode 和正文

问题描述 投票:0回答:3

我想使用 VTL 解析 API 网关集成响应中的“statusCode”和“body”值,并将它们作为方法响应返回,如下所示:

Request status: 201
Response body: {"firstName":"He","lastName":"Man","email":"[email protected]"}

我的 API Gateway Step Function 集成返回以下集成响应正文(这是在转换之前,从输出中删除不相关的属性):

{
  "output": "{\"statusCode\":201,\"body\":{\"firstName\":\"He\",\"lastName\":\"Man\",\"email\":\"[email protected]\"}}"
}

我认为这是可行的:

#set ($output = $util.parseJson($input.json('$.output')))
#set ($statusCode = $output.statusCode)
#set ($context.responseOverride.status = $statusCode)
$output.body

但状态未更新且正文为空

Request status: 200
Response body: <empty>

通过这种方法我可以解析正文:

#set ($bodyObj = $util.parseJson($input.body))
#set ($output = $util.parseJson($bodyObj.output))
#set ($context.responseOverride.status = $output.statusCode)
$output.body

statusCode 已更新,但正文以对象表示形式返回,即不是 JSON。

Request status: 201
Response body: {firstName=He, lastName=Man, [email protected]}

在上述情况下如何将 $output.body 正确序列化为 JSON? API Gateway 似乎没有像 AppSync 那样具有 $util.toJson 功能(https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-programming-guide.html )

我已经确认解析输出变量工作正常:

#set ($output = $util.parseJson($input.json('$.output')))
$output
Request status: 200
Response body: {"statusCode":201,"body":{"firstName":"He","lastName":"Man","email":"[email protected]"}}

相关参考文档:

amazon-web-services aws-step-functions api-gateway vtl
3个回答
1
投票

我遇到了这个问题。确实似乎没有办法直接转换为 JSON,所以我设计了一种使用 Apache VTL 将 JSON 写入 API 网关响应的方法:

#set ($outputObj = $util.parseJson($input.path('$.output')))
#foreach ( $key in $outputObj.body.keySet() )
  "$key": $outputObj.body[$key] #if ($foreach.hasNext),#end
#end

希望这有帮助!

(这适用于您所描述的简单用例,但不能推广到嵌套对象等)


1
投票

我遇到了同样的问题。我最后就是这样解决的。 @noahtk7 提供的解决方案对于简单对象很有用,我有需要的大型嵌套对象。

为此,您需要将正文作为 Base64 编码字符串返回。这在步骤函数中很容易做到。例如:

"Pass": {
  "Type": "Pass",
  "Next": "Success",
  "Parameters": {
    "Base64.$": "States.Base64Encode(States.JsonToString($.Response.Body))"
  },
  "ResultPath": "$.Response.Body"
}

然后在 api 响应映射器中:

#set($output = $util.parseJson($input.path('$.output')))
#set($context.responseOverride.status = $output.Response.Status)

$util.base64Decode($output.Response.Body.Base64)

会给我一个结果:

{
    "foo": "bar",
    "Id": "c2b2220c-00e3-4499-87c0-d06ea5e5f1f4"
}

0
投票

在另一个帖子中看到类似的答案,但现在找不到了。

output
值是JSON字符串而不是VTL。对象的其余部分
$
VTL
。我们还需要将 JSON 转换为 VTL。

#set ($output = $util.parseJson($input.path('$.output')))
#set ($input.path('$').response = $output)
$input.json('$.response.body')

因此第一行创建原始

VTL
值的
output
表示。然后我们只需要把它插回
$
(参见第 2 行的
.response
),这样我们就可以使用
$input
方法来获取我们需要的内容(参见第 2 行和第 3 行)。注:

© www.soinside.com 2019 - 2024. All rights reserved.