Search code examples
jsongoamazon-dynamodbaws-sdk-goaws-sdk-go-v2

Convert DynamoDB JSON to AttributeValue, Go Object or Json


I am trying to convert simple DynamoDB Object string:

{
  "Item": {
    "Id": {
      "S": "db31"
    },
    "CreateTime": {
      "N": "1647882237618915000"
    }
}

to either dynamodb.AttributeValue and then map to a go object (go type structure) or convert to a simple JSON go object.

I think, there are similar answers (1, 2, 3) in Java, but I didn't find a similar implementation in Golang.


Solution

  • You could create a struct type and use json.Unmarshal to unmarshal the JSON string like this:

    package main
    
    import (
        "encoding/json"
        "fmt"
        "os"
    )
    
    type Record struct {
        Item struct {
            Id struct {
                S string
            }
            CreateTime struct {
                N string
            }
        }
    }
    
    func main() {
    
        str := `{
      "Item": {
        "Id": {
          "S": "db31"
        },
        "CreateTime": {
          "N": "1647882237618915000"
        }
      }
    }`
    
        var record Record
        if err := json.Unmarshal([]byte(str), &record); err != nil {
            fmt.Fprintf(os.Stderr, "unmarshal failed: %v", err)
            os.Exit(1)
        }
    
        fmt.Printf("%s %s", record.Item.Id.S, record.Item.CreateTime.N)
    }
    
    

    If you want a different approach, and want to transform the result into a structure that is different than the JSON, you could use a library like gjson.

    Here is an example "flattening" the result into a simpler struct:

    package main
    
    import (
        "fmt"
        "github.com/tidwall/gjson"
    )
    
    type Record struct {
        Id         string
        CreateTime string
    }
    
    func main() {
    
        str := `{
      "Item": {
        "Id": {
          "S": "db31"
        },
        "CreateTime": {
          "N": "1647882237618915000"
        }
      }
    }`
    
        values := gjson.GetMany(str, "Item.Id.S", "Item.CreateTime.N")
    
        record := Record{
            Id:         values[0].Str,
            CreateTime: values[1].Str,
        }
    
        fmt.Printf("%s %s", record.Id, record.CreateTime)
    }