You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用VTL解析Step Function输出时,如何正确序列化API网关响应Body?

API Gateway VTL解析Step Functions响应并序列化JSON体

问题描述

需要通过VTL从API Gateway与Step Functions集成的响应中,解析出statusCode和body,最终返回如下格式的方法响应:

Request status: 201
Response body: {"firstName":"He","lastName":"Man","email":"he.man@eternia.com"}

集成响应的原始结构(已移除无关属性):

{
  "output": "{\"statusCode\":201,\"body\":{\"firstName\":\"He\",\"lastName\":\"Man\",\"email\":\"he.man@eternia.com\"}}"
}

尝试过的VTL代码及问题:

  1. 初始代码(状态码未更新,响应体为空):
#set ($output = $util.parseJson($input.json('$.output')))
#set ($statusCode = $output.statusCode)
#set ($context.responseOverride.status = $statusCode)
$output.body

返回结果:

Request status: 200
Response body: <empty>
  1. 调整后代码(状态码正确,但body输出为对象格式而非标准JSON):
#set ($bodyObj = $util.parseJson($input.body))
#set ($output = $util.parseJson($bodyObj.output))
#set ($context.responseOverride.status = $output.statusCode)
$output.body

返回结果:

Request status: 201
Response body: {firstName=He, lastName=Man, email=he.man@eternia.com}

已确认$output解析正常:

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

返回结果:

Request status: 200
Response body: {"statusCode":201,"body":{"firstName":"He","lastName":"Man","email":"he.man@eternia.com"}}

核心问题:API Gateway VTL没有类似AppSync的$util.toJson函数,如何将$output.body正确序列化为标准JSON字符串?

解决方案

方法1:直接截取原始JSON片段

利用output本身是JSON字符串的特性,直接提取其中的body部分,无需将body解析为对象:

#set ($rawOutput = $input.json('$.output'))
#set ($output = $util.parseJson($rawOutput))
#set ($context.responseOverride.status = $output.statusCode)
#set ($bodyStart = $rawOutput.indexOf('"body":') + 7)
#set ($bodyEnd = $rawOutput.lastIndexOf('}'))
$rawOutput.substring($bodyStart, $bodyEnd)

说明:通过定位"body":的起始位置,截取原始JSON中body对应的完整JSON片段,直接输出即可得到标准JSON格式的响应体。

方法2:调用Java Jackson工具类序列化对象

API Gateway VTL支持调用Java类,使用Jackson的ObjectMapper将解析后的body对象序列化为JSON:

#set ($bodyObj = $util.parseJson($input.body))
#set ($output = $util.parseJson($bodyObj.output))
#set ($context.responseOverride.status = $output.statusCode)
#set ($mapper = new com.fasterxml.jackson.databind.ObjectMapper())
$mapper.writeValueAsString($output.body)

说明:通过实例化Jackson的ObjectMapper,调用其writeValueAsString方法将Java对象转换为标准JSON字符串。

方法3:修正初始代码的输入处理逻辑

初始代码的问题在于$input.json('$.output')的使用方式,改用$input.body先解析整个响应体,再结合方法2的序列化逻辑,也能得到正确结果:

#set ($fullResponse = $util.parseJson($input.body))
#set ($output = $util.parseJson($fullResponse.output))
#set ($context.responseOverride.status = $output.statusCode)
#set ($mapper = new com.fasterxml.jackson.databind.ObjectMapper())
$mapper.writeValueAsString($output.body)

关键原理

  • 当使用$util.parseJson解析output后,$output.body会被转换为Java对象(如LinkedHashMap),直接输出时会采用Java对象的默认toString()格式,而非JSON结构。
  • API Gateway VTL未内置JSON序列化工具函数,但可通过字符串截取或调用Java JSON工具类两种方式实现需求。

内容的提问来源于stack exchange,提问作者villekr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 16:58:58