AWS Lambda の関数の中に DynamoDB のアクセスを記述するようにします。
ここでは、以下を実現します。
- Lambda 関数から、DynamoDBをアクセスします。
- Cognito認証とLambdaで協調しアクセス制限をします。
- mynote-sample-lambda.zip
- 実行方法は、サンプルコードの実行方法を参照してください。
MyNote - Lambda を使用した DynamoDB アプリケーション


| 設定項目 | 設定値 |
|---|---|
| AWS サービス | Amazon DynamoDB |
| アクション | BatchGetItem BatchWriteItem DeleteItem GetItem PutItem Query UpdateItem UpdateTable |
| Amazon リソースネーム | DynamoDB のテーブルのARN |












console.log('Loading mynote_lambda function');
var AWS = require("aws-sdk");
var m_dynamodbDoc = null;
var table = "Notes";
var regin = "<リージョン名>";
exports.handler = function(event, context) {
switch (event.func) {
case 'getNoteList':
execGetNoteList(event, context);
break;
case 'updateNote':
execUpdateNote(event, context);
break;
case 'addNote':
execUpdateNote(event, context);
break;
case 'clearAll':
execClearAll(event, context);
break;
case 'deleteNote':
execDeleteNote(event, context);
break;
default:
console.log('unknown event.func=' + event.func);
break;
}
};
function execGetNoteList(event, context) {
openDb();
getNoteList(context.identity.cognitoIdentityId, function(isSuccess, data) {
if (isSuccess) {
context.succeed({"operation" : "new", "notes" : data});
} else {
context.fail("failed getNoteList: " + data);
}
});
}
function execUpdateNote(event, context) {
openDb();
updateNote(context.identity.cognitoIdentityId, event.param, function(isSuccess, data) {
if (isSuccess) {
context.succeed({"operation" : "add", "note" : data});
} else {
context.fail("failed updateNote: " + data);
}
});
}
function execClearAll(event, context) {
openDb();
clearAll(context.identity.cognitoIdentityId, function(isSuccess, data) {
if (isSuccess) {
context.succeed({"operation" : "new", "notes" : []});
} else {
context.fail("failed clearAll: " + data);
}
});
}
function execDeleteNote(event, context) {
openDb();
deleteNote(context.identity.cognitoIdentityId, event.param.date_time, function(isSuccess, data) {
if (isSuccess) {
context.succeed({"operation" : "delete", "note" : data});
} else {
context.fail("failed deleteNote: " + data);
}
});
}
function openDb() {
if (m_dynamodbDoc === null) {
console.log('start open dynamoDB');
AWS.config.update({
region: region,
endpoint: "https://dynamodb." + region + ".amazonaws.com"
});
m_dynamodbDoc = new AWS.DynamoDB.DocumentClient();
console.log('end open dynamoDB');
}
}
function getNoteList(userId, callback) {
console.log("userId", userId);
var params = {
"TableName" : table,
"KeyConditionExpression": "user_id = :userId",
"ExpressionAttributeValues": {
":userId": userId
}
};
console.log("query param ", JSON.stringify(params));
m_dynamodbDoc.query(params, function(err, data) {
var notes = [];
if (err) {
var errStr = "Unable to query. Error:" + JSON.stringify(err, null, 2);
console.log(errStr);
callback(false, errStr);
} else {
console.log("Query succeeded.");
var itemSize = data.Items.length;
if (itemSize === 0) {
callback(true, notes);
} else {
data.Items.forEach(function(item) {
console.log(" -", JSON.stringify(item));
var note = {
"user_id" : item.user_id,
"date_time" : item.date_time,
"text_type" : item.text_type,
"text" : item.text
};
notes.push(note);
});
callback(true, notes);
}
}
});
}
function updateNote(userId, item, callback) {
var params = {
"TableName" : table,
"Item" : {
"user_id" : userId,
"date_time" : item.date_time,
"text_type" : item.text_type,
"text" : item.text
}
};
console.log("Adding a new item...", JSON.stringify(params));
m_dynamodbDoc.put(params, function(err, data) {
if (err) {
console.error("Unable to add item. Error JSON:", JSON.stringify(err, null, 2));
callback(false, JSON.stringify(err));
} else {
console.log("Added item:", JSON.stringify(data, null, 2));
callback(true, params.Item);
}
});
}
function deleteNote(userId, dateTime, callback) {
var data = {
user_id: userId,
date_time: dateTime
};
var dataList= [];
dataList.push(data);
deleteItems(dataList, function(isSuccess, deletedItems) {
if (isSuccess) {
callback(isSuccess, deletedItems[0]);
} else {
callback(isSuccess, deletedItems);
}
});
}
function clearAll(userId, callback) {
var params = {
"TableName" : table,
"KeyConditionExpression": "user_id = :userId",
"ExpressionAttributeValues": {
":userId": userId
}
};
console.log("query param ", JSON.stringify(params));
m_dynamodbDoc.query(params, function(err, data) {
var notes = [];
if (err) {
var errStr = "Unable to query. Error: " + JSON.stringify(err, null, 2);
console.log(errStr);
callback(false, errStr);
} else {
console.log("Query succeeded.");
deleteItems(data.Items, callback);
}
});
}
function deleteItems(items, callback) {
params = {
"RequestItems": {
}
};
var deletedItems = [];
params.RequestItems[table] = [];
console.log("test ", JSON.stringify(params));
items.forEach(function(item) {
console.log(" -", JSON.stringify(item));
var request = {
"DeleteRequest" : {
"Key": {
"user_id": item.user_id,
"date_time" : item.date_time
}
}
};
params.RequestItems[table].push(request);
deletedItems.push({
"user_id": item.user_id,
"date_time" : item.date_time
});
});
console.log("delete req:", JSON.stringify(params));
m_dynamodbDoc.batchWrite(params, function(err, data) {
if (err) {
var errStr = "Unable to batchWriteItem. Error: " + JSON.stringify(err, null, 2);
console.log(errStr);
callback(false, errStr);
} else {
console.log("batchWriteItem succeeded.");
callback(true, deletedItems);
}
});
}
{
func: "要求機能",
param: 要求パラメータ
}
ユーザーIdは、Cognito認証して、Lambda Function の invoke をすると、Lambda の context.identity.cognitoIdentity で取得することができるので、パラメータとはしません。| 機能 | func | param |
|---|---|---|
| Noteリストの取得 | 'getNoteList' | {} |
| Noteの追加 | 'addNote' |
{
date_time : 日時,
text : テキスト
}
|
| Noteの更新 | 'updateNote' |
{
date_time : 日時,
text : テキスト
}
|
| Noteの削除 | 'deleteNote' |
{
date_time : 日時
}
|
| 全Noteの削除 | 'clearAll' | {} |
| 設定項目 | 設定値 |
|---|---|
| AWS サービス | AWS Lambda |
| アクション | Invoke Function |
| Amazon リソースネーム | DynamoDB のテーブルのARN |





cognito.js で、認証してユーザーが使用する role ARN に先ほど作成した、ロールを指定するようにします。
function Cognito() {
var m_roleArn = role の ARN;
var m_identityPoolId = cognito のプールID;
この指定によって、cognitoに認証したユーザーが、MyNodeFunc の Lambda function にアクセスできるようになります。
Lmbdaアクセスは、dbControllerLambda.js で行います。
Cognitoを使用したアプリケーション作成のときのように、index.html のdbContoller を入れ替えるだけで、Lambdaを使ったアクセスができるようになります。
function initApp() {
…
g_dbControllerLambda = new DbControllerLambda();
g_dbControllerLambda.init();
g_doc.setDbController(g_dbControllerLambda);
function invoke(payLoad, callback) {
console.log('AWS.config=');
console.log(AWS.config);
var lambda = new AWS.Lambda();
var params = {
FunctionName : 'MyNoteFunc',
InvocationType : 'RequestResponse',
Payload : JSON.stringify(payLoad)
};
lambda.invoke(params, function(err, data) {
if (err) {
console.log('error:' + err);
callback(false, err);
} else {
if (data.FunctionError) {
console.log('function error:' + data);
callback(false, data.Payload);
}
} else {
console.log(data);
callback(true, JSON.parse(data.Payload));
}
}
});
}
this.getNoteList = function(userId, callback) {
var payload = {
func : 'getNoteList',
param : {}
};
invoke(payload, function(isSuccess, data) {
if (isSuccess) {
callback(true, data.operation, data.notes);
} else {
callback(false, data, null);
}
});
};
その他の機能は、dbControllerLambda.js の実装を参照してください。
c:\projects>cd mynote c:\projects\mynote>npm install
var g_region = '<リージョン名>';
var m_roleArn = '<Role ARN>'; var m_identityPoolId = '<cognito identity pool id>';
var region = "<リージョン名>";