Back

Explore Courses Blog Tutorials Interview Questions
0 votes
2 views
in AWS by (19.1k points)

I'm trying to set-up an AWS-lambda using aws-sdk-go that is triggered whenever a new user is added to a certain dynamodb table.

Everything is working just fine but I can't find a way to unmarshal a map map[string]DynamoDBAttributeValue like:

{

    "name": {

        "S" : "John"

    },

    "residence_address": {

        "M": {

            "address": {

                "S": "someplace"

            }

        }

    }

}

To a given struct, for instance, a User struct. Here is shown an example of unmarshalling a map[string]*dynamodb.AttributeValue into a given interface, but I can't find a way to do the same thing with map[string]DynamoDBAttributeValue even though these types seem to fit the same purposes. 

map[string]DynamoDBAttributeValue is returned by a events.DynamoDBEvents from package github.com/aws/aws-lambda-go/events. This is my code: 

package handler

 

import (

    "context"

    "github.com/aws/aws-lambda-go/events"

    "github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute"

    "github.com/aws/aws-sdk-go/service/dynamodb"

)

 

func HandleDynamoDBRequest(ctx context.Context, e events.DynamoDBEvent) {

 

    for _, record := range e.Records {

 

        if record.EventName == "INSERT" {

 

            // User Struct

            var dynamoUser model.DynamoDBUser

 

            // Of course this can't be done for incompatible types

            _ := dynamodbattribute.UnmarshalMap(record.Change.NewImage, &dynamoUser)

        }

 

    }

 

}

Of course, I can marshal record.Change.NewImage to JSON and unmarshal it back to a given struct, but then, I would have to manually initialize dynamoUser attributes starting from the latter ones.

Or I could even write a function that parses map[string]DynamoDBAttributeValue to map[string]*dynamodb.AttributeValue like: 

func getAttributeValueMapFromDynamoDBStreamRecord(e events.DynamoDBStreamRecord) map[string]*dynamodb.AttributeValue {

    image := e.NewImage

    m := make(map[string]*dynamodb.AttributeValue)

    for k, v := range image {

        if v.DataType() == events.DataTypeString {

            s := v.String()

            m[k] = &dynamodb.AttributeValue{

                S : &s,

            }

        }

        if v.DataType() == events.DataTypeBoolean {

            b := v.Boolean()

            m[k] = &dynamodb.AttributeValue{

                BOOL : &b,

            }

        }

        // . . .

        if v.DataType() == events.DataTypeMap {

            // ?

        }

    }

    return m

}

And then simply use dynamodbattribute.UnmarshalMap, but on events.DataTypeMap it would be quite a tricky process.

Is there a way through which I can unmarshal a DynamoDB record coming from a events.DynamoDBEvent into a struct with a similar method shown for map[string]*dynamodb.AttributeValue?

closed

1 Answer

0 votes
by (44.4k points)
selected by
 
Best answer

There where few problems with events.DataTypeList, try this:

// UnmarshalStreamImage converts events.DynamoDBAttributeValue to struct

func UnmarshalStreamImage(attribute map[string]events.DynamoDBAttributeValue, out interface{}) error {

 

    dbAttrMap := make(map[string]*dynamodb.AttributeValue)

 

    for k, v := range attribute {

 

        var dbAttr dynamodb.AttributeValue

 

        bytes, marshalErr := v.MarshalJSON(); if marshalErr != nil {

            return marshalErr

        }

 

        json.Unmarshal(bytes, &dbAttr)

        dbAttrMap[k] = &dbAttr

    }

 

    return dynamodbattribute.UnmarshalMap(dbAttrMap, out)

 

}

Related questions

Want to get 50% Hike on your Salary?

Learn how we helped 50,000+ professionals like you !

0 votes
1 answer
0 votes
1 answer
0 votes
1 answer

Browse Categories

...