API Gateway映射模板嵌套对象写法及转换失败问题排查
问题排查与修复方案
核心错误原因
你的映射模板存在三个关键问题,导致请求转换失败:
- 表单参数处理的边界异常:当请求体包含无值的参数(如
key=或仅key)时,$token.split('=')返回的数组长度不足2,访问$keyVal[1]会触发索引越界,直接中断转换流程。 - JSON构造方式错误:VTL中直接用
{ ... }构造的是VTL哈希对象,并非合法JSON字符串。后续$util.escapeJavaScript($body)会将对象转为类似{context={proxy={source_ip=xxx}}}的非JSON格式字符串,导致Step Function无法解析。 - 转义逻辑顺序错误:未先将VTL对象转为标准JSON字符串就直接转义,生成的
input字段内容不符合Step Function的格式要求。
修复后的映射模板(推荐方案)
利用API Gateway内置的参数解析能力,避免手动拆分请求体的风险:
#set($bodyObj = { "context": { "proxy": { "source_ip": "$context.identity.sourceIp", "http_method": "$context.httpMethod", "request_id": "$context.requestId", "url": "$context.domainName" } }, "payload": $util.toJson($input.params()) }) { "input": "$util.escapeJavaScript($util.toJson($bodyObj))", "stateMachineArn": "arn:aws:states:us-east-1:12345:stateMachine:name" }
手动处理请求体的兼容方案(如需自定义解析)
如果必须手动拆分原始请求体,需添加边界情况处理:
#set($payload = {}) #set($rawBody = $input.path('$')) #if($rawBody && $rawBody != '') #foreach($token in $rawBody.split('&')) #set($keyVal = $token.split('=', 2)) #set($key = $util.urlDecode($keyVal[0])) #set($val = '') #if($keyVal.size() > 1) #set($val = $util.urlDecode($keyVal[1])) #end #set($void = $payload.put($key, $val)) #end #end #set($bodyObj = { "context": { "proxy": { "source_ip": "$context.identity.sourceIp", "http_method": "$context.httpMethod", "request_id": "$context.requestId", "url": "$context.domainName" } }, "payload": $payload }) { "input": "$util.escapeJavaScript($util.toJson($bodyObj))", "stateMachineArn": "arn:aws:states:us-east-1:12345:stateMachine:name" }
修复说明
- 使用
$input.params()直接获取API Gateway解析后的表单/查询参数,无需手动拆分,避免边界错误。 - 用
$util.toJson()将VTL哈希对象转为标准JSON字符串,再通过$util.escapeJavaScript()转义,确保input字段是符合要求的JSON格式字符串。 - 手动处理时,通过
split('=', 2)避免参数值包含=的情况,同时判断数组长度防止索引越界。
内容的提问来源于stack exchange,提问作者preceptor
相关产品推荐
相关产品推荐

