AWS API GatewayからLambdaを呼んでDynamoDBからデータを読み出すメモ。
事前準備と前提条件
- AWS CLIを使えるようにしておく。
- リージョンは us-east-1 でやった。東京リージョンはまだAPI Gatewayが使えないという情報があったので(未確認)。
DynamoDBにテーブルを作る
aws dynamodb create-table --attribute-definitions AttributeName=id,AttributeType=N AttributeName=timestamp,AttributeType=N --table-name reinvent2015_iot_ph_demo_dynamodb --key-schema AttributeName=id,KeyType=HASH AttributeName=timestamp,KeyType=RANGE --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=2
Hash key: id
Range key: timestamp
です。
Lambdaにfunctionを作る
aws lambda create-function --function-name get_item --runtime nodejs --handler index.handler --role arn:aws:iam::941798529319:role/lambda_dynamo --zip-file fileb://Downloads/get_item-c93eb7e3-4bff-4e2b-a541-ebd93c608849.zip
--role
の引数を良く理解してない。Webコンソールで作ったやつのHTMLソースから<option>
タグのvalueをコピペしたら動いた。CLIだけでやるなら、予めRoleを作ってからそれを指定する、とかやるんだろうきっと。
--zip-file
の引数にはLambdaのWebコンソールからダウンロードしたzipファイルを指定した。中身は index.js
が入ってて、その中身は以下の通り。
console.log('Loading function');
var doc = require('dynamodb-doc');
var dynamo = new doc.DynamoDB();
exports.handler = function(event, context) {
console.log('Received event:', JSON.stringify(event, null, 2));
var params = {};
params.TableName = "reinvent2015_iot_ph_demo_dynamodb";
params.KeyConditions = [dynamo.Condition("id", "EQ", 1),
dynamo.Condition("timestamp", "GE", isNaN(parseFloat(event.timestamp)) ? (new Date().getTime() / 1000 - 180) : parseFloat(event.timestamp))];
dynamo.query(params, function(err, data) {
if (err) {
context.fail(new Error('Unknown error occured'));
} else {
var response = {"items":data.Items};
context.succeed(response);
}
});
};
Webコンソールでは直接コードをいじれるので、いざとなればコピペでイケる。
API Gatewayを作る
AWS CLIが未対応なので、Webコンソールでやる手順を書く。(REST APIはあるので、がんばれば作れるらしいけど…)
- https://console.aws.amazon.com/apigateway/home?region=us-east-1#/apis を開く。
-
Create API
ボタンを押して適当な名前を付けて作る。 -
Create Method
ボタンを押してGET
メソッドを作る。 - Integration Type = Lambda Function, Lambda Region = us-east-1, Lambda Function =
get_item
- Integration Request → Add mapping Template → Content-Type =
application/json
- 編集ボタン(右に出てきた鉛筆アイコン)を押して Template のテキストエリアに以下のコードを貼り付けて保存する。保存ボタン(チェックマークみたいなアイコン)を押すのを忘れずに。
{
"id": "$input.params('id')",
"timestamp": "$input.params('timestamp')"
}
-
TEST
ボタン押して動いたらOK。Deploy API
ボタンを押してデプロイして完了。おつした。
API GatewayにCORSを設定する
- OPTIONS Methodを作る。
- 作ったMethodを開く。
- Method Response → ▼ → Add Header →
Access-Control-Allow-Origin
Access-Control-Allow-Methods
Access-Control-Allow-Origin
を追加・保存する。 - Integration Response → ▼ → Header Mappings → Access-Control-Allow-Headers =
'Content-Type,X-Amz-Date,Authorization,X-Requested-With,X-Requested-By,X-Api-Key'
Access-Control-Allow-Methods ='GET,POST'
Access-Control-Allow-Origin ='*'
を追加・保存する。
- GET MethodのResponseを設定する。
- Method Response → ▼ → Add Header →
Access-Control-Allow-Origin
Access-Control-Allow-Methods
Access-Control-Allow-Origin
を追加・保存する。 - Integration Response → ▼ → Header Mappings → Access-Control-Allow-Origin =
'*'
を追加・保存する。
- Method Response → ▼ → Add Header →
あとがき
Lambdaすげー。もうこういう時代なんだなあ…