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

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

https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/request-response-data-mappings.html

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

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

```json:リクエストパラメータ
str=str&num=2
```

```json:リクエストボディ
{
    "str": "str",
    "num": 1,
    "bool": true
}
```

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

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

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

```:マッピングテンプレート
{
  "val": $input.body
}
```

```json:レスポンス本文
{
  "statusCode": 200,
  "body": {
    "val": {
      "str": "str",
      "num": 1,
      "bool": true
    }
  }
}
```

## $input.json(x)
この関数は、JSONPath の式を評価し、結果を JSON 文字列で返します。

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

### case1

```:マッピングテンプレート
{
  "val": $input.json("str")
}
```

```json:リクエスト本文
{
  "statusCode": 200,
  "body": {
    "val": "str"
  }
}
```

### case2

```:マッピングテンプレート
{
  "val": $input.json('num')
}
```

```json:リクエスト本文
{
  "statusCode": 200,
  "body": {
    "val": 1
  }
}
```

### case3

```:マッピングテンプレート
{
  "val": "$input.json('num')"
}
```

```json:リクエスト本文
{
  "statusCode": 200,
  "body": {
    "val": "1"
  }
}
```

### case4

```:マッピングテンプレート
{
  "val": $input.json('$') 
}
```

```json:リクエスト本文
{
  "statusCode": 200,
  "body": {
    "val": {
      "str": "str",
      "num": 1,
      "bool": true
    }
  }
}
```

### case5

メモ：`'$.'`っている？

```:マッピングテンプレート
{
  "val": $input.json('$.num')
}
```

```json:リクエスト本文
{
  "statusCode": 200,
  "body": {
    "val": 1
  }
}
```



## $input.json('$.pets')
pets 構造を表す JSON 文字列を返します。

メモ：謎

### case1

```:マッピングテンプレート
{
  "val": $input.json('$.pets')
}
```

```json:リクエスト本文
{
  "statusCode": 200,
  "body": {
    "val": ""
  }
}
```

### case2

```:マッピングテンプレート
{
  "val": "$input.json('$.pets')"
}
```

```json:リクエスト本文
{"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()
}
```

```json:リクエスト本文
{"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()"
}
```

```json:リクエスト本文
{
  "statusCode": 200,
  "body": {
    "val": "{path={}, querystring={str=str, num=2}, header={}}"
  }
}
```


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

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

### case1

```:マッピングテンプレート
{
  "val": $input.params('str')
}
```

```json:リクエスト本文
{"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')"
}
```

```json:リクエスト本文
{
  "statusCode": 200,
  "body": {
    "val": "str"
  }
}
```

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

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

### case1

```:マッピングテンプレート
{
  "val": $input.path('str')
}
```

```json:リクエスト本文
{"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')"
}
```

```json:リクエスト本文
{
  "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"
}
```