やりたいこと
GoでのdynamoDBに対しての操作は割とめんどかったりします。単純なStringやIntのものであればまだ良いのですが、ListのMapのなかのListとか、値の構造が複雑になってくると気が滅入ります。
// シンプルなパターン
&dynamodb.UpdateItemInput{
TableName: aws.String("sampleTable"),
Key: // 省略,
ExpressionAttributeValues: map[string]*dynamodb.Attribute{
":ssv": {
S: aws.String("sampleStringValue")
},
":siv": {
N: aws.String(strconv.Itoa(0)) // ここもintをstringに型変換してそれをaws.String()してkeyにはNを指定って感じでわかりづらい。
},
},
UpdateExpression: aws.String("set sampleStringValue=:ssv and sampleIntValue=:siv")
}
// 複雑なパターン
&dynamodb.UpdateItemInput{
TableName: aws.String("sampleTable"),
Key: //省略,
ExpressionAttributeValues: map[string]*dynamodb.Attribute{
":slv": {
L: [
{
M: {
":smp": {
aws.String("sample")
}....
}
}
]
},
}
}
これを楽にやれるのがsdk-goのexpressionってやつです。
expressionの使い方
update := expression.UpdateBuilder{}.Set(
expression.Name("sampleComplexValue"),
expression.Value(sampleCompexValue)
)
expr, err := expression.NewBuilder().WithUpdate(update).Build()
&dynamodb.UpdateItemInput{
TableName: aws.String("sampleTable"),
Key: //省略,
ExpressionAttributeNames: expr.Names(),
ExpressionAttributeValues: expr.Values(),
UpdateExpression: expr.Update()
}
上の例よりかなりスマートにかけますね。可読性も格段に上がります。
expression.Valuesの引数に複雑な(もちろん単純なものでもなんの問題もありませんが)値を渡すだけで、ここまでできるのは結構ありがたい。
もちろんexpressionは上記の例のような更新処理だけでなく、Query処理等にも使えるので積極的に使っていきたいところですね。