[AWS Lambda / API Gateway] queryStringParameter(URL クエリ文字列パラメータ) をLambda関数内で取得する

# 概要

この記事では、`http://example.com/books/1?hoge=2`というリクエストURL内の`hoge=2`の部分、もしくは`2`のことを`queryStringParameter`(URL クエリ文字列パラメータ)と呼びます。

この、`queryStringParameter`を`API Gateway`経由で`AWS Lambda`に渡すための設定を記載しました。

# 前提・対象者

- 既に`API Gateway`経由で`AWS Lambda`の関数を呼び出すことは成功している
- リクエストURLの末尾に`queryStringParameter`を記載しているのに、Lambda関数内で取得できない

この状況に陥っている方向けの記事になります。
（私がこの状態で2時間程度悩みました....）

# 症状

本来であれば、lambdaのhandler関数の`event`引数に`queryStringParameter`が渡されるはずなのにもかかわらず、`event`引数の中身が空っぽの辞書になってしまう。

```python:app_name/lambda_function.py

def lambda_handler(event, context):
    print(event) # <- こうしておけば CloudWatch の EventLog で確認できる
    return {
        'statusCode': 200,
        'headers': {
            # INFO: CORS関係のエラー回避のために必要
            'Access-Control-Allow-Origin': '*'
        },
        # 普通こんなことしないけど、結果を見るために設定
        'body': json.dumps(event)
    }
```

```javascript:APIGatewayへのリクエスト
// お好みのブラウザの開発者ツールで実行できます
>> const API_URL = 'https://xxxxxxxxxx.execute-api.us-east-2.amazonaws.com/default/tradehist'
>> var response = fetch(API_URL + '?hoge=123').then(response => response.json())
>> response
```

結果は、responseの中身を見ても、そもそも`queryStringParameters`のkeyすらない...。


# 対策

event引数に`queryStringParameters`が含まれるようにするため、以下のことを実施

## 方法の概要

`API Gateway`の「リソース」を開いた上で以下の項目を操作しました。

1. 該当「メソッドリクエスト」で「URL クエリ文字列パラメータ」を設定
1. 該当メソッドの「統合リクエスト」で「Lambda プロキシ統合の使用」にチェックを入れる
1. 「アクション」のうち「APIのデプロイ」を実行

## 方法の詳細

### 1. 該当「メソッドリクエスト」で「URL クエリ文字列パラメータ」を設定
![2020-08-29_12h30_42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327407/78b52f51-7782-19fc-996e-7914748a3c30.png)
① `API Gateway`の「リソース」を開く
② 該当メソッドを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327407/a7f1a9af-f63e-ebcf-8a4e-c154033875ea.png)
③「メソッドリクエスト」の編集画面に入る
![2020-08-29_12h36_45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327407/32970a22-2556-3e38-5d2c-502ad19f4652.png)
![2020-08-29_12h37_49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327407/7b187197-d921-240d-6026-7dc36dba421c.png)
④⑤⑥⑦URL クエリ文字列パラメータとして取得したい（認識して欲しい）パラメータ名を設定（今回なら`hoge`と入力した）

### 2. 該当メソッドの「統合リクエスト」で「Lambda プロキシ統合の使用」にチェックを入れる

![2020-08-29_12h43_59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327407/83850c8b-ef3b-6ae8-2cdd-3b0fa9dc4547.png)
①該当メソッドの「統合リクエスト」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327407/6208d8a5-c88f-818d-0f03-72502bb12d61.png)
②「Lambdaプロキシ統合の使用」にチェックを入れる

### 3. 「アクション」のうち「APIのデプロイ」を実行

![2020-08-29_12h47_47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327407/84d8f967-5899-0eff-1af9-0d86734167f6.png)
①②「APIのデプロイ」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327407/54944e85-c0e4-4a27-7ac9-3ddd5b23aedc.png)
③「デプロイされるステージ」を選択
④「デプロイ」実行

### 補足

デプロイ実行直後だと、デプロイ前の状態が維持されていることがある。
反映まではタイムラグがあるとみてよさそう。

ちなみに、私の場合は1~3分程度で反映された。


## 結果

```javascript:APIGatewayへ再リクエスト
>> const API_URL = 'https://xxxxxxxxxx.execute-api.us-east-2.amazonaws.com/default/tradehist'
>> var response = fetch(API_URL + '?hoge=123').then(response => response.json())
>> response
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327407/3b8e3d41-795f-f19e-c2a3-271c1bd112ab.png)


# 感想

ITの勉強というより、AWSサービスの使い方の勉強をしないとやっていけなくなってきた。
全然使い方がわからない(´;ω;｀)

# 関連記事

以下の記事には別のやり方が書いてある。

- [Amazon API GatewayでAWS Lambda関数にクエリ文字列をパラメータとして渡す](https://qiita.com/yuyakato/items/89fcef9746afbf48977a)
- [How to pass a querystring or route parameter to AWS Lambda from Amazon API Gateway](https://stackoverflow.com/questions/31329958/how-to-pass-a-querystring-or-route-parameter-to-aws-lambda-from-amazon-api-gatew)

どちらの方法もやり方がわからなかったのであきらめたのですが、おそらく「Lambda プロキシ統合の使用」をしない場合に、「統合リクエスト」編集ページに表示されている箇所の入力が必要になると思われる。