[[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| |プライマリキー|isbn(文字列)| |プライマリキー|id(数値)| |デフォルト設定の使用|off| |セカンダリインデックス|title(文字列)| |セカンダリインデックス|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 }}