【AWS】APIGatewayからLambdaへリクエストヘッダー情報を受け渡す

# はじめに
APIGatewayからLambdaへリクエストヘッダー情報を受け渡す必要があり、
その際に行った実装方法とテスト方法について、備忘録として記載します。

前提
　・本記事では、下記の赤矢印①〜②の実装方法について記載する。
![API_lambda_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1255237/6b5f27ad-2d81-d9fb-a9c0-7a637487486b.png)

# 目次
[1. Lambda関数の作成](https://qiita.com/drafts/19dba5d3ef8955f3b2d1/edit#1-lambda%E9%96%A2%E6%95%B0%E3%81%AE%E4%BD%9C%E6%88%90)
[2. APIGatewayの作成](https://qiita.com/drafts/19dba5d3ef8955f3b2d1/edit#2-apigateway%E3%81%AE%E4%BD%9C%E6%88%90)
[(おまけ1)Lambda関数のテスト実行](https://qiita.com/drafts/19dba5d3ef8955f3b2d1/edit#%E3%81%8A%E3%81%BE%E3%81%911lambda%E9%96%A2%E6%95%B0%E3%81%AE%E3%83%86%E3%82%B9%E3%83%88%E5%AE%9F%E8%A1%8C)
[(おまけ2)APIGatewayのテスト実行](https://qiita.com/drafts/19dba5d3ef8955f3b2d1/edit#%E3%81%8A%E3%81%BE%E3%81%912apigateway%E3%81%AE%E3%83%86%E3%82%B9%E3%83%88%E5%AE%9F%E8%A1%8C)

# 1. Lambda関数の作成
### 1-1. 関数の作成
Lambda（関数）のコンソール画面から下記の設定値でLambda関数を作成する。

|設定項目|設定値|
|:---|:---|
|以下のいずれかのオプションを選択して、関数を作成します。|一から作成|
|関数名|任意の値|
|ランタイム|Python 3.8|
|アーキテクチャ|x86_64|
|実行ロール|基本的な Lambda アクセス権限で新しいロールを作成|

### 1-2. ソースコード実装
1-1にて作成したLambda関数のコンソール画面にて、下記の内容を参考にソースコードを実装する。
今回は、リクエスト情報の受け取り確認のため、受け取ったヘッダー項目とボディパラメータ項目を返却値として設定する。

```python:lambda_function.py
def lambda_handler(event, context):
	try:
		# パラメータ設定
		# ヘッダー項目取得
		headerItem = event['headers']['Header-item']
		# ボディパラメータ項目取得
		bodyItem = event['body']['body_item']

		# 取得結果を返却
		return {
	    		'headerItem': headerItem,
	    		'bodyItem': bodyItem
		}
	    
	except Exception as e:
		# エラー
		print(e)
```


# 2. APIGatewayの作成
### 2-1. APIの作成
API Gateway（API）のコンソール画面から下記の設定値でAPIを作成する。

|設定項目|設定値|
|:---|:---|
|API タイプを選択|REST API（構築）|
|プロトコルを選択する|REST|
|新しい API の作成|新しい API|
|API 名|任意の値|
|説明|任意の値|
|エンドポイントタイプ|リージョン|

### 2-2. メソッドの作成
2-1で作成したAPI Gateway（API）のコンソール画面にて、
[アクション] > [メソッドの作成] から下記の設定値でメソッドを作成する。

|設定項目|設定値|
|:---|:---|
|メソッド|POST|
|統合タイプ|Lambda関数|
|プロキシ統合の使用|なし|
|Lambdaリージョン|1でLambda関数を作成したリージョン|
|Lambda関数|1で作成したLambda関数|
|デフォルトタイムアウトの使用|あり|

### 2-3. リクエストヘッダーの設定
2-1で作成したAPI Gateway（API）のコンソール画面にて、
[リソース（POST）] > [メソッドリクエスト] > [HTTP リクエストヘッダー] から下記の設定値でリクエストヘッダーを設定する。

|設定項目|設定値|
|:---|:---|
|名前|Header-item|
|必須|なし|
|キャッシュ|なし|

### 2-4. リクエストパラメータマッピングの設定
2-1で作成したAPI Gateway（API）のコンソール画面にて、
[リソース（POST）] > [統合リクエスト] > [マッピングテンプレート] から下記の設定値でリクエストパラメータマッピングを設定する。
![API_lambda_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1255237/7265a10b-58eb-6581-f3e7-eb72e19073a8.png)

|設定項目|設定値|
|:---|:---|
|リクエスト本文のパススルー|テンプレートが定義されていない場合 (推奨)|
|Content-Type|application/json|
|「テンプレートの生成」項目下部のテキスト入力欄|※下記のテンプレートを設定|

※下記のテンプレートを設定する。

```
{
    "method": "$context.httpMethod",
    "body" : $input.json('$'),
    "headers": {
        #foreach($param in $input.params().header.keySet())
        "$param": "$util.escapeJavaScript($input.params().header.get($param))"
        #if($foreach.hasNext),#end
        #end
    }
}
```

### 2-5. APIのデプロイ
2-1で作成したAPI Gateway（API）のコンソール画面にて、
[アクション] > [APIのデプロイ] から下記の設定値でAPIをデプロイする。

|設定項目|設定値|
|:---|:---|
|デプロイされるステージ|新しいステージ|
|ステージ名|任意の値|

# (おまけ1)Lambda関数のテスト実行
1で作成したLambda関数に対して、単体テスト実行を行う。

1にて作成したLambda関数のコンソール画面にて、「テスト」タブを選択する。
適当な名前を入力し、下部のテキスト入力欄に下記のテストテンプレートをもとに設定する。
　※body_item: 任意のボディパラメータ項目
　※Header-item: 任意のヘッダー項目

```
{
  "method": "POST",
  "body": {
    "body_item": "test-body"
  },
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate, br",
    "Content-Type": "application/json",
    "Header-item": "test-header",
    "Host": "",
    "Postman-Token": "",
    "User-Agent": "",
    "X-Amzn-Trace-Id": "",
    "X-Forwarded-For": "",
    "X-Forwarded-Port": "443",
    "X-Forwarded-Proto": "https"
  }
}
```

「変更を保存」→「テスト」ボタン押下でテスト実行する。
![API_lambda_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1255237/ee7f8f1c-5e56-913e-627d-abe5eb2270d7.png)

# (おまけ2)APIGatewayのテスト実行
2-1で作成したAPI Gateway（API）のコンソール画面にて、
作成したAPIおよびLambda関数に対して、テスト実行を行う。

[リソース（POST）] > [クライアント（テスト）] から下記の設定値でテストを実行する。

|設定項目|設定値|
|:---|:---|
|ヘッダー|Header-item:test-header|
|リクエスト本文|{ "body_item": "test-body" }|

# 参考
[カスタムの Lambda 統合を使用して、API Gateway 経由で Lambda 関数にカスタムヘッダーを渡すにはどうすれば良いですか?](https://aws.amazon.com/jp/premiumsupport/knowledge-center/custom-headers-api-gateway-lambda/)
[APIGW リクエスト検証とは？実装する方法までわかりやすく解説！-その１](https://blog.serverworks.co.jp/request-validation-with-apigw-1)