概要
リクエストボディに URL パスパラメータを追加するマッピングテンプレートを書きたかったが、盛大にはまったのでメモを残しておく。
マッピングテンプレートとは何か
以下は公式ドキュメントである。
以下は API Gatewayのマッピングテンプレートについて ChatGPT の説明である。
API Gatewayのマッピングテンプレートとは、リクエストやレスポンスのデータ形式を変換するためのスクリプトです。これにより、異なるフォーマットのデータをAPIが期待する形式に整えたり、外部サービスとの統合時にデータを適切に送信したりできます。主にVelocity Template Language (VTL)を使って記述され、JSONPathを使ってデータを操作します。
やりたかったこと
以下のリソース /books/{bookId}
に PUT メソッドを定義した。
リクエストボディは以下の形式である。
{
"title": "sample title",
"pages": [
{
"page": "1",
"content": "This is a sample content."
},
{
"page": "2",
"content": "This is also a sample content."
}
]
}
このボディに bookId: sampleId
を追加したい。
結論としては以下の記述で実現できる。
#set($inputRoot = $input.path('$'))
{
"bookId": "$input.params('bookId')",
"title": "$inputRoot.title",
"pages": [
#foreach($page in $inputRoot.pages)
{
"page": "$page.page",
"content": "$page.content"
}#if($foreach.hasNext),#end
#end
]
}
マッピングテンプレートによる変換後の JSON は以下である。
{
"bookId": "ab236276-34a5-4e2a-ae6e-3dfe7796c33a",
"title": "sample title",
"pages": [
{
"page": "1",
"content": "This is a sample content."
},
{
"page": "2",
"content": "This is also a sample content."
}
]
}
解説
- 元のリクエストボディを変数
inputRoot
に格納する
#set($inputRoot = $input.path('$'))
- URL パスパラメータを取得する
"$input.params('bookId')"
なお、URL パスパラメータは以下のように設定する。
- オブジェクトが要素である配列を記述する
"pages": [
#foreach($page in $inputRoot.pages)
{
"page": "$page.page",
"content": "$page.content"
}#if($foreach.hasNext),#end
#end
]
所感
試行錯誤して書き方が分かった今では、公式ドキュメントが結局わかりやすかったことに気づいた。以下は公式ドキュメントに記載されている例である。
#set($inputRoot = $input.path('$'))
[
#foreach($elem in $inputRoot)
{
"description" : "Item $elem.id is a $elem.type.",
"askingPrice" : $elem.price
}#if($foreach.hasNext),#end
#end
]
※注意点はダブルクォーテーションである。数値型にはダブルクォーテーションは書かない:$elem.price
あと大事なことはマッピングテンプレート編集後、API をデプロイすること。