- 追加された行はこの色です。
- 削除された行はこの色です。
[[AWSメモ]] > AWS LambdaからDynamoDBに接続する
* AWS LambdaからDynamoDBに接続する [#rc647fb9]
#setlinebreak(on);
#contents
-- 関連
--- [[AWSメモ]]
--- [[AWS LambdaからRDSに接続する]]
-- 参考
--- http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS.html
--- http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB.html
--- http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/DocumentClient.html
** テーブルの作成 [#m2b060dc]
[[マネージメントコンソールのDynamoDB>https://ap-northeast-1.console.aws.amazon.com/dynamodb/home?region=ap-northeast-1#]] から以下の通りテーブルを作成する
|項目名|値|h
|テーブル名|books|
|プライマリキー|id(数値)|
|デフォルト設定の使用|off|
|セカンダリインデックス|isbn(文字列)|
|~|title(文字列)|
|IAM ロール| 新しいロール: DynamoDBAutoscaleRole|
** Lambda関数を作成する [#a2a77bd0]
[[マネージメントコンソールのLambda>https://ap-northeast-1.console.aws.amazon.com/lambda/home?region=ap-northeast-1#/functions]] から、以下の通りLambda関数を作成する。
|項目|値|h
|関数名|dynamo-example|
|ロール|AWSLambdaFullAccess、AmazonDynamoDBFullAccess、CloudWatchLogsFullAccess を持つロール( 無い場合は作成する )|
#html(<div style="color:#f00;font-weight:bold;">)
DynamoDBへのアクセスを AWS.DynamoDB で行うのか AWS.DynamoDB.DocumentClient で行うのかが悩ましいが、
ここではシンプルに書けそうな AWS.DynamoDB.DocumentClient でコーディングする。(いったん)
※恐らく、それぞれシーンに適した使い方があるのだと思うが。
#html(</div>)
http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB.html
http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/DocumentClient.html
関数コード
#mycode2(){{
'use strict';
var AWS = require('aws-sdk');
//var dynamodb = new AWS.DynamoDB();
var documentClient = new AWS.DynamoDB.DocumentClient();
const createResponse = (callback, statusCode, body) => {
var res = {
"statusCode": statusCode,
"headers": { "Test-Headr1": "1234" },
"body": JSON.stringify(body)
}
callback(null, res);
}
exports.handler = (event, context, callback) => {
let id = false;
if (event.pathParameters){
id = event.pathParameters.id || false;
}
let req = event.body;
if (typeof(event.body) === "string") {
// TODO: 暫定(JSON文字列を受け取った場合のパース)
let jsonBody = event.body.replace(/=/g,":").replace(/&/g, ",").replace(/([^:,]+):([^:,]*)/g, "\"$1\":\"$2\"");
req = JSON.parse("{"+jsonBody+"}");
}
switch(event.httpMethod){
case "GET":
if(id && id > 0) {
var params = {
TableName : 'Books',
FilterExpression : 'id = :id',
ExpressionAttributeValues : {':id' : parseInt(id,10) }
};
documentClient.scan(params, function(err, data) {
if (err) {
console.log(err);
createResponse(callback, 500, { "msg": "Get Error!", "err": err});
} else {
createResponse(callback, 200, data);
console.log(data);
}
});
return;
} else {
var params = {
TableName : 'Books'
};
documentClient.scan(params, function(err, data) {
if (err) {
console.log(err);
createResponse(callback, 500, { "msg": "List Error!", "err": err});
} else {
createResponse(callback, 200, data);
console.log(data);
}
});
}
break;
case "POST":
var params = {
TableName : 'Books',
Item: {
"id" : parseInt(req.id, 10),
"isbn" : req.isbn,
"title" : req.title,
"price" : parseInt(req.price,10)
}
};
documentClient.put(params, function(err, data) {
if (err) {
console.log(err);
createResponse(callback, 500, { "msg": "Create Error!", "err": err, "req": req});
} else {
createResponse(callback, 200, { "msg": "Create OK!"});
}
});
break;
case "PUT":
var params = {
TableName : 'Books',
Key: { "id" : parseInt(id, 10) },
ExpressionAttributeNames: {
"#isbn" : "isbn",
"#title" : "title",
"#price" : "price"
},
ExpressionAttributeValues: {
":isbn" : req.isbn,
":title" : req.title,
":price" : parseInt(req.price, 10)
},
UpdateExpression: "SET #isbn = :isbn, #title = :title, #price = :price"
};
documentClient.update(params, function(err, data) {
if (err) {
console.log(err);
console.log(data);
createResponse(callback, 500, { "msg": "Update Error!", "err": err});
} else {
createResponse(callback, 200, { "msg": "Update OK!"});
}
});
break;
case "DELETE":
var params = {
TableName : 'Books',
Key: { "id" : parseInt(id, 10) }
};
documentClient.delete(params, function(err, data) {
if (err) {
console.log(err);
console.log(data);
createResponse(callback, 500, { "msg": "Delete Error!", "err": err});
} else {
createResponse(callback, 200, { "msg": "Delete OK!"});
}
});
break;
default:
// Send HTTP 501: Not Implemented
console.log("Error: unsupported HTTP method (" + event.httpMethod + ")");
createResponse(callback, 501, { "msg": "Error: unsupported HTTP method (" + event.httpMethod + ")" } );
}
}
}}
** API Gateway の作成 [#oc5e4c8a]
[[マネージメントコンソールのAPI GateWay>https://ap-northeast-1.console.aws.amazon.com/apigateway/home?region=ap-northeast-1#/apis]] から、以下の通りAPIを作成する。
API 名: lambda-example-api
#html(<div style="display:inline-block">)
#html(<div style="border:1px solid #333;display:inline-block;">)
&ref(api-gateway.png);
#html(</div>)
#html(</div>)
#html(<div style="display:inline-block;vertical-align:top;margin-left:20px;">)
URI一覧
|URI|メソッド|説明|h
|/book|GET|一覧取得用|
|/book|POST|登録用|
|/book/{id}|GET|一意検索用|
|/book/{id}|PUT|更新用|
|/book/{id}|DELETE|削除用|
#html(</div>)
#html(<div style="display:inline-block;vertical-align:top;margin-left:20px;">)
全メソッドとも以下の設定で作成
|項目|値|h
|統合タイプ|Lambda関数|
|Lambda プロキシ統合の使用|on|
|リージョン|ap-northeast-1|
|Lambda 関数|dynamo-example(上記で作成した関数名)|
#html(</div>)
作成後は「APIをデプロイ」からデプロイ。
** 動作確認 [#m7830598]
#myterm2(){{
# 一覧検索
curl -v https://エンドポイント/book
# 一意検索
curl -v https://エンドポイント/book
# 登録
curl -v -XPOST --data "id=1&isbn=A0001&title=test00A&price=1111" https://エンドポイント/book
# 更新
curl -v -XPUT --data "isbn=B0001&title=test00B&price=2222" https://エンドポイント/book/1
# 削除
curl -v -XDELETE https://エンドポイント/book/1
}}