使用映射模板添加或更新 JSON 对象的属性 (AWS API Gateway)

Chr*_*ith 5 vtl aws-api-gateway

在我的 AWS APIGW Rest API 中,我尝试添加和/或更新提交的请求正文 (JSON) 上的属性。我能找到的每个示例都涉及构建新的 JSON 对象,而不是更新现有对象。

在集成请求映射模板中,我的传入数据正文如下所示。如果发布的是新对象,则它不会有 ID。如果它是一个现有对象,它将有一个 ID。 这里的目标是始终确保它具有 ID,方法是获取现有 ID 并将其设置回 JSON 对象或添加新 ID。

// New object getting added, No ID
{
    "first_name" : "Toby",
    "last_name" : "Keith"
}


// Existing object getting updated, Has ID
{
    "id" : "abcdef"
    "first_name" : "Toby",
    "last_name" : "Keith"
}
Run Code Online (Sandbox Code Playgroud)

我的集成请求映射模板如下所示:

## Do we have an existing id? (this is correctly pulling the existing ID)
#set( $id = $input.path('$.id') )
## If no ID, create one using the RequestID.  (This is also working)
#if ( $id == "" ) #set( $id = $context.requestId ) #end
## Get the entire json request string as json object
#set( $json_obj = $input.json('$') )
## Overwrite the ID on the json body to make sure we always have one
## [HERE IS THE PROBLEM]
## This isn't setting the id back on the $json_obj
#set( $input.path('$.id') = "$id" )
{
    "data": "$util.escapeJavaScript($json_obj).replaceAll("\\'","'")"
}
Run Code Online (Sandbox Code Playgroud)

我希望上面“data”的值是一个 JSON 字符串,其中包含 id 以及名字和姓氏。

我已经尝试了多种设置属性的变体,但到目前为止还没有运气。这些都不起作用。

// Tries to update the JSON string I think, not the $json_obj
#set( $input.path('$.id') = "$id" )
// These cause error (because of quotes?)
#set( "$json_obj.id" = "BBBB" )
#set( '$json_obj.id' = "CCCC" )
// Doesn't work
#set( $input.path("$json_obj.id") = "DDDD" )
#set( $json_obj.id = "EEEE" )
Run Code Online (Sandbox Code Playgroud)

作为 B 计划,我可以将 $json_obj 分解为键/值对,然后循环检查 ID,然后添加或更新它。本质上是构建一个新的 JSON 对象,但这似乎比直接设置属性不太好。

有谁知道如何使用映射模板添加/更新 JSON 对象上的属性?

Chr*_*ith 10

我发现了这个问题。这行代码并没有像我想象的那样将主体有效负载转换为 JSON 对象。更仔细地阅读文档后我发现它检查 JSON 路径表达式并返回匹配的 JSON 字符串。

#set( $json_obj = $input.json('$') )
Run Code Online (Sandbox Code Playgroud)

要将其转换为对象,我需要以下语法:

#set( $json_obj = $util.parseJson($input.json('$')) )
Run Code Online (Sandbox Code Playgroud)

更正后的映射模板现在如下所示

## Do we have an existing id? (this is correctly pulling the existing ID)
#set( $id = $input.path('$.id') )
## If no ID, create one using the RequestID.  (This is also working)
#if ( $id == "" ) #set( $id = $context.requestId ) #end
## Get the entire json request string as json object
#set( $json_obj = $util.parseJson($input.json('$')) )
## Overwrite the ID on the json body to make sure we always have one
## This isn't setting the id back on the $json_obj
#set( $input.path('$.id') = "$id" )
{
    "data": "$util.escapeJavaScript($json_obj).replaceAll("\\'","'")"
}
Run Code Online (Sandbox Code Playgroud)

然而,这导致了第二个问题,即现在将 JSON 对象转换回格式正确的 JSON 字符串。如果我打印出 JSON 对象,由于某种原因我会得到不带引号的字符串。

# Print out $json_obj 
$page_obj
Run Code Online (Sandbox Code Playgroud)

结果是

{first_name=Toby, last_name=Keith}
Run Code Online (Sandbox Code Playgroud)

如果我无法解决该问题,我将提出一个新问题。

2021/11/30 更新:

我从事这个项目已经有一段时间了,但为了完整起见,我最终能够在将对象拉入 JSON 之前在输入上设置 ID。

## Pull the existing ID
#set( $id = $input.path('$').id )
## If empty, assign new ID
#if ( $id == "" ) #set ( $id = $context.requestId ) #end
## Assign the ID to the input
#set( $input.path('$').id = $id )
## Now pull the data out as an object
#set( $data = $input.json('$') )
Run Code Online (Sandbox Code Playgroud)

path('$.id')现在真正的区别是path('$').id,在将输入提取到 JSON 对象之前,将 id 正确分配给输入。