godynamo-local

how to unmarshal a map from DynamoDB to struct?


There is the following field on dynamo

{

      "config": {
        "BASE_AUTH_URL_KEY": "https://auth.blab.bob.com",
        "BASE_URL": "https://api.dummy.data.com",
        "CONN_TIME_OUT_SECONDS": "300000",
        "READ_TIME_OUT_SECONDS": "300000"
      },
      "id": "myConfig"
    }
and getting the element with dynamodbattribute

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

    result, err := svc.GetItem(&dynamodb.GetItemInput{
        TableName: aws.String(tableName),
        Key: map[string]*dynamodb.AttributeValue{
            "id": {
                S: aws.String(configId),
            },
        },
    })

this code its working but when i try to retrieve the object its rendered like this

    map[config:{
      M: {
        BASE_AUTH_URL_KEY: {
          S: "https://auth.blab.bob.com"
        },
        CONN_TIME_OUT_SECONDS: {
          S: "300000"
        },
        READ_TIME_OUT_SECONDS: {
          S: "300000"
        },
        BASE_URL: {
          S: "https://api.dummy.data.com"
        }
      }
    } id:{
      S: "myConfig"
    }]

for that reason when i try to unmarshal my object the object unmarshalled returns as {}

type Config struct {
    id                  string
    baseAuthUrlKey      string
    baseUrl             string
    connectTimeOutSecs  string
    readTimeOutSecs     string
}

item := Config{}
err = dynamodbattribute.UnmarshalMap(result.Item, &item)

how can i assign the value return from the GetItem that seems to be a map to my struct ?


Solution

  • The root of the issue is that your Config struct is incorrectly structured.

    I recommend using json-to-go when converting JSON to Go structs; this tool will help you catch issues like this in the future.

    Once you get your struct constructed correctly, you'll also notice that your struct fields are not capitalized, meaning they will not be exported (i.e. able to be used by other packages), which is another reason that your UnmarshalMap code will not return the result you are expecting.

    Here is a good answer on struct field visibility and its importance, briefly summarized above.

    Below is a corrected version of your struct that, combined with your UnmarshalMap code, will correctly allow you to print your item and not receive a {} which is no fun.

    type Item struct {
        Config struct {
            BaseAuthUrlKey     string `json:"BASE_AUTH_URL_KEY"`
            BaseUrl            string `json:"BASE_URL"`
            ConnTimeoutSeconds string `json:"CONN_TIME_OUT_SECONDS"`
            ReadTimeoutSeconds string `json:"READ_TIME_OUT_SECONDS"`
        } `json:"config"`
        ID string `json:"id"`
    }