API Gateway から Lambda にパラメータを渡す

10月で入社して半年が経ちました、streampackチームのminsuです。
いきなり寒くなってきて秋を感じますね、春に東京に引っ越してきた私はまだ冬服を揃えてないのでもう少し緩やかに気温が変化して欲しかったです。

今回の記事は先日API Gateway + Lambdaを触ることがあったため、自分用にまとめたものです。
/{foo}/{bar}のようなパスパラメータやGET,POSTパラメータを渡そうとしたところ、
`マッピングテンプレート`を設定する方法もありますが`Lambdaプロキシ統合`を使うとよしなに設定してくれて楽でした。

## Lambda 関数の作成
Lambda関数を作成します。
関数名は`params-test`としました。
アクセス権限は用途に沿って設定してください。
![スクリーンショット 2019-10-17 17.45.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399734/c3230c25-e9cc-a3b1-03ac-68383f78db5f.png)

## API Gateway 作成
`APIの作成`から API を作成します、API名はURLに反映されません。
![スクリーンショット 2019-10-17 17.49.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399734/9a434cb6-0023-db12-2683-3e8ba0798662.png)

### リソース作成
パスパラメータを設定するには`リソースの作成`するときに`リソースパス`を`{}`で括ります。
![スクリーンショット 2019-10-17 17.53.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399734/a64deff6-510b-52a5-6367-0f7d1463100b.png)

### メソッド作成
`メソッドの作成`>GETを選択し、メソッドのセットアップを行います。
Lambda関数に先ほど作成した `params-test`を入力します。
前述の`Lambda プロキシ統合の使用`に チェックを入れることでリクエスト情報が Lambda の handler関数の event で参照できるようになります。
![スクリーンショット 2019-10-17 18.00.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399734/c8e72623-4130-ed1c-af5e-96c24263a03a.png)
メソッド作成後も`統合リクエスト`から編集可能です。

### API のデプロイ
アクションからAPIのデプロイを行います。
ここのステージ名はURLに反映されます。
`https://xxx.execute-api.ap-northeast-1.amazonaws.com/ステージ名`
![スクリーンショット 2019-10-18 11.46.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399734/c719cef2-8193-9170-7bf5-b68f8204c806.png)

Lambda でテストをしたい場合は イベントテンプレート `Amazon API Gateway AWS Proxy`を選択して`pathParameters`を編集するといいです。

## Lambdaへリクエストデータの引き渡し
API Gateway へパラメータを付けてGETリクエストを行うと Lambda の event は以下のフォーマットで情報を受け取ります。

```
$ curl https://xxx.execute-api.ap-northeast-1.amazonaws.com/dev/xxx/foofoo/barbar?hoge=hogege&fuga=fugaga
```

```json

{
    "resource": "/xxx/{foo}/{bar}",
    "path": "/xxx/foofoo/barbar",
    "httpMethod": "GET",
    "headers": {...},
    "multiValueHeaders": {...},
    "queryStringParameters": {
        "fuga": "fugaga",
        "hoge": "hogege"
    },
    "multiValueQueryStringParameters": {...},
    "pathParameters": {
        "bar": "barbar",
        "foo": "foofoo"
    },
    "stageVariables": null,
    "requestContext": {...},
    "body": null,
    "isBase64Encoded": false
}
```

`pathParameters`にパスパラメータが、
`queryStringParameters`にGETパラメータが含まれて Lambda に渡されています。
これがPOSTリクエストの場合は`body`にPOSTパラメーターが渡されます。

Lambda関数の言語に沿って
node.js では `event.pathParameters.foo;`
python では `event['pathParameters']['foo']`
ruby では `event['pathParameters']['foo']`
のようにパラメータを取得できます。



Lambda側でテストを行う場合はイベントテンプレート`Amazon API Gateway AWS Proxy`を使用すると一通りフォーマットが揃っています。
API Gateway側でテストを行う場合はメソッドの実行画面からテストが行えます。

Lambda への入力フォーマット
https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format

## API Gatewayへのレスポンスデータ
Lambda プロキシ統合を設定すると Lambda から API Gateway へのレスポンスデータも以下のフォーマットに沿って渡されます。

```json
{
    "isBase64Encoded": true|false,
    "statusCode": httpStatusCode,
    "headers": { "headerName": "headerValue", ... },
    "multiValueHeaders": { "headerName": ["headerValue", "headerValue2", ...], ... },
    "body": "..."
}
```

以下のように `headers` `Access-Control-Allow-Origin` を追加することでCORSを有効にできるなど工夫が必要なようです。

```js

exports.handler = async (event) => {
    const hoge = event.queryStringParameters.hoge;
    const body = {
        "hoge": hoge,
    };
    const response = {
        statusCode: 200,
        headers: {
          "Access-Control-Allow-Origin": "*"
        },
        body: JSON.stringify(body),
    };
    return response;
};
```

API Gateway へのレスポンスフォーマット
https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-output-format

## 感想
API Gateway と Lambdaをチェックボックス一つで連携できるのは便利でした。
決まったフォーマットがあるのは覚えておかなければですね。
「API Gateway から Lambda にパラメータを渡す」というテーマでしたが、実際に利用する場合はLambdaからのレスポンスも理解が必要ですね、今後の課題です。

## 参考
Lambdaプロキシ統合
https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html
マッピングテンプレート
https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/apigateway-getting-started-with-rest-apis.html