AWSのLambdaとDynamoDBとAPIGatewayの連携

2017/7/8　現在の情報です。

# 作る順番

DynamoDB→Lambda→APIGatewayの順番に作っていきます。


# 下準備～IAMロールの作成～
IAMにロールの作成が必要です。
今回はLambdaからDynamoDBを呼び出させるので先に以下作業を行っておきます。

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

ロールタイプの選択画面が出るので、「AWS Lambda」を選択
ポリシーの設定画面が出るので

* AmazonDynamoDBFullAccess
* AWSLambdaDynamoDBExecutionRole

を選択します。
※他の記事を読むと、「AWSLambdaDynamoDBExecutionRole」だけで良いと書いてあったんですが
　なんかダメでした。

名前決めろって言われるので適当に「lambda-dynamodb-execution-role」とかにします。

で、ためらわず作成。


# DynamoDBの設定

DynamoDBの画面よりテーブルの作成ボタンを押す
テーブル名、PKを決めろって言われるので適当に決める。
今回は適当にHogeテーブル、fugaカラム名にします。

しばらくしたら出来上がるので、項目タブ　＞　項目作成
ここでキー以外の項目を追加できます。piyoを追加しましょう。
追加する時についでに値も入れられるようです。

分かりにくいので図。

![dynamo.png](https://qiita-image-store.s3.amazonaws.com/0/42110/6bbecc3c-2bae-cca6-8827-516dcb000bf1.png)

左の方にあるプラスを押すと項目が増えていきます。
型を設定して、値を入れたら保存。するとpiyoカラムが追加されて、ついでに値も入ります。

はい、これでDynamoDBの設定は終わりです。簡単ですね。


# Lambdaの設定
はい、次はLambdaです。

Lambdaの画面でためらわず、Lambda関数の作成を押します。

設計図の選択と言われるので、何言ってるか分からないからBlankFunctionを選びます。
トリガーの設定画面が出ますが、何かよく分からんので次へ。
はい、次の画面、大事です。

名前：fugafuga
説明：ぴよぴよ
ランタイム：Node.js 4.3
Lambda 関数のコード
　コードをインラインで編集 を選ぶ。

こんな感じのコードを書きましょう。

```
var AWS = require('aws-sdk');
var dynamo = new AWS.DynamoDB({
    region: 'ap-northeast-1'
});
exports.handler = function(event, context) {
    var params = {
        "TableName": "Hoge",
        "KeyConditionExpression":"fuga = :fugafuga",
        "ExpressionAttributeValues": {
            ":fugafuga" : {"S": event.fugafuga}
        }
    };
    console.log("event:", event);
    dynamo.query(params, function(err, data) {
        console.log("dynamo_data:", data);
        console.log("dynamo_err:", err);
        context.done(null, data);
    });

};
```
node.js読めなくても雰囲気でわかると思います。
Dynamoにつないで、Hogeテーブルのfugaテーブルがevent.fugafugaで取得した値と
同じものを取得しそうですね。

その下の方の「Lambda 関数ハンドラおよびロール」の設定。
ハンドラを「exports.handler」と入力して下さい。
そして、ついに出ました。ロールで最初に作った「lambda-dynamodb-execution-role」を選択します。

次へ、関数を作成をためらわずに押します。


## Lambdaのテスト
テストしてみましょう。
関数作ったら上の方に嫌でも目につくテストボタン。押してみます。

謎の入力画面。パラメータを指定できそうなのでこんな感じで入力します。

```
{
  "fugafuga": "ThisisKey"
}
```

はい、やったね。上手くいきました。

```
{
  "Items": [
    {
      "fuga": {
        "S": "ThisisKey"
      },
      "piyo": {
        "S": "piyopiyopiyo"
      }
    }
  ],
  "Count": 1,
  "ScannedCount": 1
}
```

ぴよぴよ言ってますね。


# APIGatewayの設定
はい、APIGatewayです。何のためらいもなく、APIの作成ボタンを押しましょう。

新しいAPIです。API名は適当に「piyopiyo」、説明も適当に「ぴよぴよ」と入力しましょう。
するとこんな画面になります。まずはメソッドを作りましょう。
このセレクトを選んで下さい。

![apigateway.png](https://qiita-image-store.s3.amazonaws.com/0/42110/dc0dbcd8-6989-efd2-a623-729117d2bc41.png)

中身を取得したいのでGETメソッドを作りましょう。
すると何か聞かれるので「統合タイプ：Lambda関数」を選びます。せっかく作ったしね。
リージョンはap-northeast-1、Lambda関数はfugafugaでした。

保存ボタンを押すと、何か怖そうなダイアログが出ますが、怖くない、怖くない。
OKしましょう。

するとなんかイケてる画面になります。
この画面が、どこからどうAPIが呼び出されて、その後何を呼び出して、何を返すのか。
禅問答みたいですね。

![apigateway2.PNG](https://qiita-image-store.s3.amazonaws.com/0/42110/ae53e8f4-68b4-3f69-0add-d56807674b3e.png)


#パラメータの設定

APIたるものパラメータを受けて渡す必要があるでしょう。
まず受け方は、↑の図の「メソッドリクエスト」をクリックします。
すると色々設定デキそうですが今回は「URL クエリ文字列パラメータ」を設定します。
適当に「fuga」を設定します。これでfugaパラメータを受け取れるようになりました。

次に「統合リクエスト」をクリックします。
ここでは、APIGatewayからLambdaにパラメータを渡す設定をします。

本文マッピングテンプレートが隠れているので展開して
「リクエスト本文のパススルー」を「テンプレートが定義されていない場合 (推奨) 」を選択
その下の「マッピングテンプレートの追加」を押します。
するとContentTypeが設定できるので「application/json」を選択。
しかしひどいUI。

すると、その下に謎の入力箇所が現れるので、ここでやっと引き渡す値を設定できます。

```
{
    "fugafuga": "$input.params('fuga')"
}
```

はい、意味分からんですね。
$input.params('fuga') は、APIGatewayが受ける変数です。?fuga=XXX みたいな感じです。
で、左の"fugafuga"は、Lambdaのeventが受け取る変数名になります。
うえーーの方のLambdaのプログラムでevent.fugafuga って書いてたアレに入ります。


最後。「メソッドレスポンス」を選択。
普通に返却すると日本語が化けるらしく、「本文マッピングテンプレート」にこれを設定します。
「application/json;charset=UTF-8」
もともとあった「application/json」は消します。

これで完成。

## APIのデプロイから実行
はい、後はAPIをデプロイすれば使えます。
ここからデプロイを選びましょう。

![apigateway3.PNG](https://qiita-image-store.s3.amazonaws.com/0/42110/28b80836-ddb1-b0f6-7b8e-685d63827403.png)


デプロイされるステージ：新しいステージ
ステージ名：develop
説明：適当に。
ステージは本番、開発を分けるためのタグですね。
実際は何でも大丈夫です。

はい、デプロイするとURLが発行されます。
https://XXXXXX-api.ap-northeast-1.amazonaws.com/develop
みたいな感じになりますね。

これを押すと、nullが表示されると思います。寂しい。
なぜならパラメータが必要だから。
じゃあパラメータfugaを付けてみましょう。
https://XXXXXX-api.ap-northeast-1.amazonaws.com/develop?fuga=ThisisKey

```
{"Items":[{"fuga":{"S":"ThisisKey"},
"piyo":{"S":"piyopiyopiyo"}}],"Count":1,"ScannedCount":1}
```

やった！DynamoDBに入れた値が取れましたね。

はい、これで一連の作業はおしまいです。
結構調べながらやると、管理画面が過去の文言だったりフローが変わってたりと
罠が多かったので2017/7/8時点の情報でまとめました。
誰かの役に立つといいなー:sunny: