はじめに
今回はDynamoDBを利用して簡易な掲示板を作成します。
準備
DynamoDBのテーブルを作成します。
[Lambda , API Gatewayの準備をします。]
(https://qiita.com/tanaka_takurou/items/3f93295de6cff060ec09)
[参考資料]
テーブルの作成
DynamoDBのテーブル作成
WEBページ・API作成
GO言語のAWS Lambda関数ハンドラー aws-lambda-go を使用してHTMLやJSONを返す処理を作成します。
また、DynamoDB を使用するため aws-sdk-go を利用します。
[参考資料]
AWS SDK for Go API Reference
あえて aws-sdk-go で dynamoDB を使うときの基本操作
Reading an Amazon DynamoDB Table Item
今回は、ページ用とAPI用のLambda関数を別々に作成し、ページ用のメソッドはGET、API用のメソッドはPOSTに設定しました。
要素を取得する際にはScanを使う。
main.go
func scan(tableName string, filt expression.ConditionBuilder)(*dynamodb.ScanOutput, error) {
sess := session.Must(session.NewSessionWithOptions(session.Options{
SharedConfigState: session.SharedConfigEnable,
}))
svc := dynamodb.New(sess)
expr, err := expression.NewBuilder().WithFilter(filt).Build()
if err != nil {
return nil, err
}
params := &dynamodb.ScanInput{
ExpressionAttributeNames: expr.Names(),
ExpressionAttributeValues: expr.Values(),
FilterExpression: expr.Filter(),
ProjectionExpression: expr.Projection(),
TableName: aws.String(tableName),
}
return svc.Scan(params)
}
func getMessageList(room_id int, threshold int)([]MessageData, error) {
var messageList []MessageData
result, err := scan(messageTableName, expression.Name("room_id").Equal(expression.Value(room_id)))
if err != nil {
return nil, err
}
for _, i := range result.Items {
item := MessageData{}
err = dynamodbattribute.UnmarshalMap(i, &item)
if err != nil {
return nil, err
}
if item.Status >= threshold {
continue
}
messageList = append(messageList, item)
}
return messageList, nil
}
要素を挿入する際にはPutItemを使う。
main.go
func put(tableName string, av map[string]*dynamodb.AttributeValue) error {
sess := session.Must(session.NewSessionWithOptions(session.Options{
SharedConfigState: session.SharedConfigEnable,
}))
svc := dynamodb.New(sess)
input := &dynamodb.PutItemInput{
Item: av,
TableName: aws.String(tableName),
}
_, err := svc.PutItem(input)
return err
}
func putMessage(room_id int, user string, message string, icon_id int) error {
t := time.Now()
count, err := getMessageCount(room_id)
if err != nil {
return err
}
item := MessageData {
Message_Id: int(*count) + 1,
Room_Id: room_id,
Icon_Id: icon_id,
Status: 0,
User: user,
Message: message,
Created: t.Format(layout),
}
av, err := dynamodbattribute.MarshalMap(item)
if err != nil {
return err
}
err = put(messageTableName, av)
if err != nil {
return err
}
return nil
}
要素を更新する際にはUpdateItemを使う。
main.go
func update(tableName string, an map[string]*string, av map[string]*dynamodb.AttributeValue, key map[strin
g]*dynamodb.AttributeValue, updateExpression string) error {
sess := session.Must(session.NewSessionWithOptions(session.Options{
SharedConfigState: session.SharedConfigEnable,
}))
svc := dynamodb.New(sess)
input := &dynamodb.UpdateItemInput{
ExpressionAttributeNames: an,
ExpressionAttributeValues: av,
TableName: aws.String(tableName),
Key: key,
ReturnValues: aws.String("UPDATED_NEW"),
UpdateExpression: aws.String(updateExpression),
}
_, err := svc.UpdateItem(input)
return err
}
func updateMessage(message_id int, value int, name string) error {
an := map[string]*string{
"#s": aws.String(name),
}
av := map[string]*dynamodb.AttributeValue{
":new": {
N: aws.String(strconv.Itoa(value)),
},
}
key := map[string]*dynamodb.AttributeValue{
"message_id": {
N: aws.String(strconv.Itoa(message_id)),
},
}
updateExpression := "set #s = #s + :new"
err := update(messageTableName, an, av, key, updateExpression)
if err != nil {
return err
}
return nil
}
終わりに
DynamoDBは NoSQLのため慣れるまでは扱いにくく感じましたが、メリットが多くあります。
[参考資料]
DynamoDBを使いこなして精神的安定を手に入れた