[AWS] Lambda + API Gatewayでサーバレスを始める １

とりあえず、AWS Lambda と API Gateway でサクッとサーバレスをやってみます。
マネジメントコンソールから全部の実装・設定をやってしまいます。
AWS SAM とかは使ってないので、そのあたり（バージョン管理やCLIからのデプロイなど）は別の記事などで補完をお願いします。

# ロールの作成
Lambda ファンクション作成時にロールを設定する必要があるので、あらかじめ IAM でロールを作成しておきます。

IAM > ロール >  新しいロールの作成

#### ロールタイプの選択
AWS Lambda を選択。
<img width="1209" alt="スクリーンショット 2017-07-03 9.31.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/92538/cd98c461-a324-7821-d481-433192df0566.png">

#### ポリシーのアタッチ
ここで実行時に必要な権限をアタッチします（DynamoDBとかS3とかのアクセス権限）。
今回は特に何も必要ないので、AWSLambdaBasicExecutionRole をアタッチし、CloudWatch Logs へのアクセス権限のみ付与します。
チェックを入れて「次のステップへ」クリック。
<img width="1202" alt="スクリーンショット 2017-07-03 9.45.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/92538/1996a716-6bda-93ac-56eb-1924a2f104e7.png">

#### 確認
ロール名を入力し（必要ならDescriptionを入力し）、ロールの作成をクリック。
<img width="1196" alt="スクリーンショット 2017-07-03 9.49.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/92538/ace0eb30-0e9b-737d-9108-b5a4b6bbbe6d.png">


# Lambda ファンクションの作成
先に API Gateway の設定をすることもできますが、ここでは先に Lambda を書きます。

Lambda > Lambda関数の作成 > Blank Function > (トリガーは設定せずに)次へ

#### 関数の設定
関数名を入力し、ランタイムを選択します。
今回は Node.js 6.10 にします。
<img width="1214" alt="スクリーンショット 2017-07-03 9.51.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/92538/b3a85159-1185-f7e2-821e-624e7f110a81.png">

先ほど作成したロールを選択して次へ。
<img width="1197" alt="スクリーンショット 2017-07-03 10.07.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/92538/633e2592-5a10-27fc-e76c-871643a0b0b4.png">

#### 確認
内容確認して、「関数の作成」クリック。
<img width="1211" alt="スクリーンショット 2017-07-03 10.09.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/92538/299b2e01-197a-fcef-77be-5fb2866581df.png">

#### コードの変更
ひとまずJSONを返却するようにします。

```js
exports.handler = (event, context, callback) => {
    callback(null, {"name": "hoge"});
};
```

# API Gateway の設定
API Gateway > APIの作成

API名を入力して、「APIの作成」クリック。
<img width="1034" alt="スクリーンショット 2017-07-03 14.04.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/92538/5c1447a4-3b08-9f94-eb31-01309f5fa4b4.png">

#### リソース作成
リソースのアクションから、メソッドの作成を選択。
<img width="989" alt="スクリーンショット 2017-07-03 14.07.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/92538/ace34fef-aaa0-04a0-8d64-ff0baf5185cd.png">

GETを選択肢、チェックマークをクリックして確定。
セットアップ画面になるので、Lambdaを作成したリージョン※1とLambdaファンクション名※2を入力して保存。
※1 : コンソールの上部で表示されているリージョンで作成されています。東京なら「ap-northeast-1」を選択。
※2 : 最初の文字を入力すれば、候補が表示されます。
<img width="983" alt="スクリーンショット 2017-07-03 14.10.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/92538/525b81b2-d469-fc39-e2e8-96f0e7a430f8.png">

リソースが作成されたので、ひとまずテストを実行してみます。
<img width="978" alt="スクリーンショット 2017-07-03 14.16.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/92538/b257b5ea-ca28-8480-f073-bc7a41326fb4.png">

「テスト」ボタンをクリックすると、成功していることがわかります。
ステータスが200で、JSONが返ってきていることを確認してください。
<img width="978" alt="スクリーンショット 2017-07-03 14.18.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/92538/fea8cc40-3f49-357d-c8f1-1ff0d95f3402.png">

#### APIのデプロイ
リソースのアクションから「APIにデプロイ」を選択。
<img width="959" alt="スクリーンショット 2017-07-03 14.44.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/92538/1a9e11f5-8430-1dd5-5edb-fa824e2f7771.png">

「新しいステージ」を選択し、ステージ名を入力。
ここでは「prod」と入力。
<img width="874" alt="スクリーンショット 2017-07-03 14.45.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/92538/16eb00a5-f444-204f-9ec9-536eb072dc07.png">

デプロイすると、APIエンドポイントが作成されます。
<img width="986" alt="スクリーンショット 2017-07-03 14.48.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/92538/baf6fa89-fe8e-cf73-1d38-395288fd7a32.png">

# CORSの設定
CORSの設定は、 API Gateway リソースのアクションから設定できます。
<img width="881" alt="スクリーンショット 2017-07-03 14.54.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/92538/3a156aa4-d8b3-84bf-49fa-41bd8a1be0d6.png">

設定を変更したあとは、再度APIをデプロイする必要があります。

# パスパラメータ
「/prod/:id」ってしたい時の設定方法。

リソース > アクション > リソースの作成
<img width="984" alt="スクリーンショット 2017-07-03 15.15.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/92538/1927bbce-63f4-c5ff-5ff5-c6e38a00c99c.png">

新たに子リソースを追加します。
その際、リソースパスの文字列を{}で括ります。
<img width="979" alt="スクリーンショット 2017-07-03 15.17.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/92538/e48b4ee1-b1b1-e97a-048f-91d7ff027407.png">

リソース作成後、{id}にGETメソッドを作成します。
Lambdaの設定をします。
<img width="981" alt="スクリーンショット 2017-07-03 15.23.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/92538/263323a8-2b04-0bb6-fdea-26fddde248ab.png">

APIのテスト実行画面で、パスが入力可能になっていることを確認します。
<img width="947" alt="スクリーンショット 2017-07-03 15.25.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/92538/ef13e1d5-c55a-42d7-17b0-492fab0f5a91.png">

Lambdaからパラメータを取得できるように設定します。
統合リクエストをクリック。
<img width="976" alt="スクリーンショット 2017-07-03 15.31.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/92538/7b689d16-4258-6a96-165d-257a745c4394.png">

本文マッピングテンプレート > マッピングテンプレートの追加
「application/json」と入力してチェックマーククリックで確定。
<img width="983" alt="スクリーンショット 2017-07-03 15.32.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/92538/fe181471-b9f7-5d47-bcaa-4582ac8a9f8e.png">

以下のように、マッピングを記述します。
<img width="971" alt="スクリーンショット 2017-07-03 15.36.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/92538/dcaaf935-f74e-8565-93e6-f183f7f6dbcf.png">

```json
{
  "id": "$input.params('id')"
}
```

Lambdaでパラメータを取得できるようになったので、以下のように変更します。
パラメータはeventから取得できます。

```js
exports.handler = (event, context, callback) => {
    callback(null, {"id": event.id, "name": "hoge"});
};
```

テストを実行し、入力値が返ってきていることを確認してください。
<img width="976" alt="スクリーンショット 2017-07-03 15.42.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/92538/436fec01-532b-dca6-9d88-4ad51a313b2b.png">


# クエリパラメータ
「/prod?name=:name」ってしたい時の設定方法。

メソッドリクエストから設定します。
<img width="978" alt="スクリーンショット 2017-07-03 15.45.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/92538/faaf81ce-7fc7-4936-7524-e5acd12357ba.png">

URL クエリ文字列パラメータに「name」を入力し、チェックマークで確定します。
<img width="982" alt="スクリーンショット 2017-07-03 15.46.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/92538/b884aa3a-235f-118b-c61c-ef40e8b49c94.png">

パスパラメータの時と同様、統合リクエストからマッピングテンプレートを設定します。
<img width="984" alt="スクリーンショット 2017-07-03 15.48.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/92538/e03b9d77-3c82-f03c-0b21-ccaca2e4e10f.png">

Lambdaを変更します。

```js
exports.handler = (event, context, callback) => {
    callback(null, {"id": event.id, "name": event.name});
};
```

テストで、クエリ文字列が入力可能になっています。
入力値が返ってきていることを確認してください。
※idはクエリ文字列で入力できないのでundefinedになり、nameだけがJSONで返却されます。
<img width="973" alt="スクリーンショット 2017-07-03 15.57.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/92538/fc47d719-cd84-6d94-9b6d-185da11af72a.png">


# 文字化けするときは
日本語が文字化けする場合、メソッドレスポンスで文字コードを設定します。
<img width="979" alt="スクリーンショット 2017-07-03 16.02.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/92538/b20fa627-8148-4d7e-46e4-1959a0f40ab0.png">

200のレスポンス本文の「application/json」を編集（ペンマークをクリック）します。
<img width="984" alt="スクリーンショット 2017-07-03 16.05.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/92538/9b81a719-7a17-5555-1374-f81cabe3ba55.png">

「;charset=UTF-8」を追記し、保存します。
<img width="980" alt="スクリーンショット 2017-07-03 16.07.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/92538/aabcbea4-06ca-7fa3-8317-d7fa602ba79f.png">

[その２](http://qiita.com/naoki_koreeda/items/5351f8ab803db655b0b4)に続く→