I use AWS Lambda with DynamoDB using golang.
My DynamoDB table use lowercase attribute names such as id or name.
In Go, if I want to be able to marshal a struct correctly, I have to name fields starting with a capital letter.
type Item struct {
ID string
Name string
}
To put an item into my DynamoDB table, I have to marshal it into a map[string]*dynamodb.AttributeValue, using dynamodbattribute.MarshalMap function.
item := Item{
ID: "xxxx",
Name: "yyyy"
}
av, _ := dynamodbattribute.MarshalMap(item)
Of course, this will create a map using names written as ID and Name, which are incompatible with id and name from the dynamodb table.
Reading the documentation, I found that you can use a custom encoder, and enable json tags.
type Item struct {
ID string `json="id"`
Name string `json="name"`
}
func setOpts(encoder *dynamodbattribute.Encoder) {
// Not sure which one I sould set
// So I set them both :)
encoder.SupportJSONTags = true
encoder.MarshalOptions.SupportJSONTags = true
}
func main() {
encoder := dynamodbattribute.NewEncoder(setOpts)
encoder.Encode(...)
}
But here the encoder.Encode() method is only used to create a dynamodb.AttributeValue, and not a map[string]*dynamodb.AttributeValue.
Is there a way to use a custom encoder with MarshalMap? Or am I using it in a wrong way?
EDIT:
Okay so as Zak pointed out, there is a dynamodbav tag that can be used.
I also found out that I was using json tags in a wrong way. I should use the syntax json:"id" instead of json="id".
Indeed, DynamoDB SDK uses the json tag if available, and this one can be overrided by the dynamodbav.
So all I had to do was to make my structure looks like this and it worked
type Item struct {
ID string `json:"id"`
Name string `json:"name"`
}