AWS
lambda
APIGateway
サーバレスアーキテクチャ

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

More than 1 year has passed since last update.

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

ロールの作成

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

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

ロールタイプの選択

AWS Lambda を選択。
スクリーンショット 2017-07-03 9.31.23.png

ポリシーのアタッチ

ここで実行時に必要な権限をアタッチします(DynamoDBとかS3とかのアクセス権限)。
今回は特に何も必要ないので、AWSLambdaBasicExecutionRole をアタッチし、CloudWatch Logs へのアクセス権限のみ付与します。
チェックを入れて「次のステップへ」クリック。
スクリーンショット 2017-07-03 9.45.00.png

確認

ロール名を入力し(必要ならDescriptionを入力し)、ロールの作成をクリック。
スクリーンショット 2017-07-03 9.49.13.png

Lambda ファンクションの作成

先に API Gateway の設定をすることもできますが、ここでは先に Lambda を書きます。

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

関数の設定

関数名を入力し、ランタイムを選択します。
今回は Node.js 6.10 にします。
スクリーンショット 2017-07-03 9.51.41.png

先ほど作成したロールを選択して次へ。
スクリーンショット 2017-07-03 10.07.41.png

確認

内容確認して、「関数の作成」クリック。
スクリーンショット 2017-07-03 10.09.54.png

コードの変更

ひとまずJSONを返却するようにします。

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

API Gateway の設定

API Gateway > APIの作成

API名を入力して、「APIの作成」クリック。
スクリーンショット 2017-07-03 14.04.15.png

リソース作成

リソースのアクションから、メソッドの作成を選択。
スクリーンショット 2017-07-03 14.07.43.png

GETを選択肢、チェックマークをクリックして確定。
セットアップ画面になるので、Lambdaを作成したリージョン※1とLambdaファンクション名※2を入力して保存。
※1 : コンソールの上部で表示されているリージョンで作成されています。東京なら「ap-northeast-1」を選択。
※2 : 最初の文字を入力すれば、候補が表示されます。
スクリーンショット 2017-07-03 14.10.22.png

リソースが作成されたので、ひとまずテストを実行してみます。
スクリーンショット 2017-07-03 14.16.49.png

「テスト」ボタンをクリックすると、成功していることがわかります。
ステータスが200で、JSONが返ってきていることを確認してください。
スクリーンショット 2017-07-03 14.18.15.png

APIのデプロイ

リソースのアクションから「APIにデプロイ」を選択。
スクリーンショット 2017-07-03 14.44.41.png

「新しいステージ」を選択し、ステージ名を入力。
ここでは「prod」と入力。
スクリーンショット 2017-07-03 14.45.51.png

デプロイすると、APIエンドポイントが作成されます。
スクリーンショット 2017-07-03 14.48.14.png

CORSの設定

CORSの設定は、 API Gateway リソースのアクションから設定できます。
スクリーンショット 2017-07-03 14.54.42.png

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

パスパラメータ

「/prod/:id」ってしたい時の設定方法。

リソース > アクション > リソースの作成
スクリーンショット 2017-07-03 15.15.36.png

新たに子リソースを追加します。
その際、リソースパスの文字列を{}で括ります。
スクリーンショット 2017-07-03 15.17.37.png

リソース作成後、{id}にGETメソッドを作成します。
Lambdaの設定をします。
スクリーンショット 2017-07-03 15.23.44.png

APIのテスト実行画面で、パスが入力可能になっていることを確認します。
スクリーンショット 2017-07-03 15.25.03.png

Lambdaからパラメータを取得できるように設定します。
統合リクエストをクリック。
スクリーンショット 2017-07-03 15.31.25.png

本文マッピングテンプレート > マッピングテンプレートの追加
「application/json」と入力してチェックマーククリックで確定。
スクリーンショット 2017-07-03 15.32.54.png

以下のように、マッピングを記述します。
スクリーンショット 2017-07-03 15.36.18.png

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

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

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

テストを実行し、入力値が返ってきていることを確認してください。
スクリーンショット 2017-07-03 15.42.11.png

クエリパラメータ

「/prod?name=:name」ってしたい時の設定方法。

メソッドリクエストから設定します。
スクリーンショット 2017-07-03 15.45.10.png

URL クエリ文字列パラメータに「name」を入力し、チェックマークで確定します。
スクリーンショット 2017-07-03 15.46.17.png

パスパラメータの時と同様、統合リクエストからマッピングテンプレートを設定します。
スクリーンショット 2017-07-03 15.48.54.png

Lambdaを変更します。

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

テストで、クエリ文字列が入力可能になっています。
入力値が返ってきていることを確認してください。
※idはクエリ文字列で入力できないのでundefinedになり、nameだけがJSONで返却されます。
スクリーンショット 2017-07-03 15.57.57.png

文字化けするときは

日本語が文字化けする場合、メソッドレスポンスで文字コードを設定します。
スクリーンショット 2017-07-03 16.02.49.png

200のレスポンス本文の「application/json」を編集(ペンマークをクリック)します。
スクリーンショット 2017-07-03 16.05.20.png

「;charset=UTF-8」を追記し、保存します。
スクリーンショット 2017-07-03 16.07.20.png

その2に続く→