Golang and DynamoDB
How to put data into dynamodb
I have been avoiding Amazon DynamoDB for a long time. Each time I tried to use it, either with PHP or GoLang always gave up very quickly. A while ago, I built up a solution storing a lot of JSON files on S3 buckets, and the costs of this solution (number of GET requests) started to escalate very quickly. I decided to try to migrate data to DynamoDB, and this time I was successful. I will try to explain how I did it and what I learned along the way.
Generic documentation is not very clear about storing data without using “weird” notation of objects, so I thought this was the only way to go.
PutItem
If you go along documentation basic PutItem
could look like this:
out, err := svc.PutItem(context.TODO(), &dynamodb.PutItemInput{
TableName: aws.String("my-table"),
Item: map[string]types.AttributeValue{
"id": &types.AttributeValueMemberN{Value: 12346},
"name": &types.AttributeValueMemberS{Value: "John Doe"},
"email": &types.AttributeValueMemberS{Value: "john@doe.com"},
},
})
It doesn’t look very convenient to me. But if you go deeper in the documentation you can find something table_basics.go which is using attributevalue .
This magical liberate allows you to marshal your struct into a map of AttributeValue
, and you have can also power of annotations to pass additional meta value to your marshaller:
import (
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue"
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
)
type ItemStruct struct {
ID int `dynamodbav:"id"`
Name string `dynamodbav:"name"`
Email string `dynamodbav:"email"`
}
var myItem ItemStruct
myItem.ID = 12346
myItem.Name = "John Doe"
myItem.Email = "john@doe.io"
item, err := attributevalue.MarshalMapWithOptions(myItem)
if err != nil {
panic(err)
}
_, err = basics.DynamoDbClient.PutItem(context.TODO(), &dynamodb.PutItemInput{
TableName: aws.String(basics.TableName), Item: item,
})
if err != nil {
log.Printf("Couldn't add item to table. Here's why: %v\n", err)
}
return err
}
Looks much better, right?