API Gatewayのマッピングテンプレートがわからなすぎて色々試した記録


こちら公式ドキュメントですが、毎度のごとく何を行ってるのかさっぱりわからないし、どう書いたらいいかわからんじゃないかとキレたくなる。

ここではとりあえず各パターンを試行錯誤してみた結果を並べておく。

必要となればリクエストパラメータ・リクエストボディにはそれぞれ以下を指定する。

リクエストパラメータ
str=str&num=2
リクエストボディ
{
    "str": "str",
    "num": 1,
    "bool": true
}

$input 変数

$input 変数は、マッピングテンプレートによって処理されるメソッドリクエストペイロードとパラメータを示します。この変数は 4 つの関数を提供します。

$input.body

文字列として raw リクエストペイロードを返します。

メモ:リクエストボディから値を取得

マッピングテンプレート
{
  "val": $input.body
}
レスポンス本文
{
  "statusCode": 200,
  "body": {
    "val": {
      "str": "str",
      "num": 1,
      "bool": true
    }
  }
}

$input.json(x)

この関数は、JSONPath の式を評価し、結果を JSON 文字列で返します。

メモ:リクエストボディの値を取得。

case1

マッピングテンプレート
{
  "val": $input.json("str")
}
リクエスト本文
{
  "statusCode": 200,
  "body": {
    "val": "str"
  }
}

case2

マッピングテンプレート
{
  "val": $input.json('num')
}
リクエスト本文
{
  "statusCode": 200,
  "body": {
    "val": 1
  }
}

case3

マッピングテンプレート
{
  "val": "$input.json('num')"
}
リクエスト本文
{
  "statusCode": 200,
  "body": {
    "val": "1"
  }
}

case4

マッピングテンプレート
{
  "val": $input.json('$') 
}
リクエスト本文
{
  "statusCode": 200,
  "body": {
    "val": {
      "str": "str",
      "num": 1,
      "bool": true
    }
  }
}

case5

メモ:'$.'っている?

マッピングテンプレート
{
  "val": $input.json('$.num')
}
リクエスト本文
{
  "statusCode": 200,
  "body": {
    "val": 1
  }
}

$input.json('$.pets')

pets 構造を表す JSON 文字列を返します。

メモ:謎

case1

マッピングテンプレート
{
  "val": $input.json('$.pets')
}
リクエスト本文
{
  "statusCode": 200,
  "body": {
    "val": ""
  }
}

case2

マッピングテンプレート
{
  "val": "$input.json('$.pets')"
}
リクエスト本文
{"message": "Could not parse request body into json: Unexpected character (\'\"\' (code 34)): was expecting comma to separate Object entries\n at [Source: (byte[])\"{\n  \"val\": \"\"\"\"\n}\n\"; line: 2, column: 13]"}

$input.params()

すべてのリクエストパラメータのマップを返します。

メモ:リクエストパラメータから値を取得

case1

マッピングテンプレート
{
  "val": $input.params()
}
リクエスト本文
{"message": "Could not parse request body into json: Unexpected character (\'p\' (code 112)): was expecting double-quote to start field name\n at [Source: (byte[])\"{\n  \"val\": {path={}, querystring={str=str, num=2}, header={}}\n}\"; line: 2, column: 12]"}

case2

マッピングテンプレート
{
  "val": "$input.params()"
}
リクエスト本文
{
  "statusCode": 200,
  "body": {
    "val": "{path={}, querystring={str=str, num=2}, header={}}"
  }
}

$input.params(x)

パラメータ名文字列 x が指定された場合に、パス、クエリ文字列、またはヘッダー値から (この順番で検索される) メソッドリクエストパラメータの値を返します。

メモ:リクエストパラメータから値を取得

case1

マッピングテンプレート
{
  "val": $input.params('str')
}
リクエスト本文
{"message": "Could not parse request body into json: Unrecognized token \'str\': was expecting (\'true\', \'false\' or \'null\')\n at [Source: (byte[])\"{\n  \"val\": str\n}\"; line: 2, column: 14]"}

case2

マッピングテンプレート
{
  "val": "$input.params('str')"
}
リクエスト本文
{
  "statusCode": 200,
  "body": {
    "val": "str"
  }
}

$input.path(x)

JSONPath 式文字列 (x) を受け取り、結果の JSON オブジェクト表現を返します。

メモ:リクエストボディの値を取得。

case1

マッピングテンプレート
{
  "val": $input.path('str')
}
リクエスト本文
{"message": "Could not parse request body into json: Unrecognized token \'str\': was expecting (\'true\', \'false\' or \'null\')\n at [Source: (byte[])\"{\n  \"val\": str\n}\"; line: 2, column: 14]"}

case2

マッピングテンプレート
{
  "val": "$input.path('str')"
}
リクエスト本文
{
  "statusCode": 200,
  "body": {
    "val": "str"
  }
}

#set

こいつの説明が全くない。謎。
おそらく、変数に代入しているのだろうと思ったがあってるっぽい。

[参考]https://qiita.com/yoshidasts/items/ddab0ef7b983b7c5260b

#set($var = $input.json('$'))

#if #elif #else #end

これはよくあるif文。わかりそうなので省略。

#foreach

#foreach($var in $foo.list)
  #break
#end

foreachもできる。

おまけ

API Gateway → stepfunctionsを繋ぐ場合の設定。

マッピングテンプレートで呼び出す先のステートマシンARNを指定する。
inputに渡した値がstatemachineに渡されるので、リクエストヘッダーやボディの情報を格納するにはここをいじってあげることでできる。

{
  "input": "$util.escapeJavaScript($input.json('$'))",
  "stateMachineArn": "arn:aws:states:us-east-1:xxxxxxxxxxxx:stateMachine:HelloWorld"
}