noIdeaAtAll
noIdeaAtAll

Reputation: 203

Go AWS, marshal to JSON from DynamoDB Item, omit null values

I'm trying to query my DynamoDB table and convert the results to a json string.

sess, _ := session.NewSession(&aws.Config{
    Region: aws.String("eu-central-1")},
)
dyn = dynamodb.New(sess)

var limit int64 = 5
out, err := dyn.Scan(&dynamodb.ScanInput{
    TableName: aws.String("Products"),
    Limit: &limit,
})

b, _ := json.Marshal(out.Items[0])
fmt.Println(string(b))

But the result is unfortunately filled with NULLs, and I don't want to send the whole thing over the wire:

"Price":{"B":null,"BOOL":null,"BS":null,"L":null,"M":null,"N":"17119","N
S":null,"NULL":null,"S":null,"SS":null}

I know that this has to do with the dynamo.AttributeValue type. Is it possible to omit null values?

Thank you.

Upvotes: 1

Views: 4384

Answers (4)

Agustin Cout
Agustin Cout

Reputation: 1

this is not exactly what you ask for, but it can help you to convert a map[string]*dynamodb.AttributeValue to string without null fields.

Surely exists a better way to do this, but this is how I rapidly solve my problem with Dynamo AttributeValues nulls for now.

I hope this can help you

func GetDynamoAttributeString(newImage dto.Transaction) string {
   newImageDynamoItem, _ := dynamodbattribute.MarshalMap(newImage)
   newImageBytesItem, _ := json.Marshal(newImageDynamoItem)

   var newImageItemMap map[string]interface{}

   _ = json.Unmarshal(newImageBytesItem, &newImageItemMap)
   removeNulls(newImageItemMap)

   newImageStringItem, _ := json.Marshal(newImageItemMap)

   return string(newImageStringItem)
}

func removeNulls(m map[string]interface{}) {
    val := reflect.ValueOf(m)
    for _, e := range val.MapKeys() {
        v := val.MapIndex(e)
        if v.IsNil() {
            delete(m, e.String())
            continue
        }
        switch t := v.Interface().(type) {
        // If key is a JSON object (Go Map), use recursion to go deeper
        case map[string]interface{}:
            removeNulls(t)
        }
    }
}

Reference to remove null fields on golang maps: https://www.ribice.ba/golang-null-values/

Upvotes: 0

mediastream
mediastream

Reputation: 253

You can omit NULL values during marshaling by adding omitempty like this

type Person struct {
    Name    string
    Email   string   `dynamodbav:",omitempty"`
    Friends []string `dynamodbav:",omitemptyelem"`
}

godocs type Encoder

Upvotes: 0

noIdeaAtAll
noIdeaAtAll

Reputation: 203

So I found "an" answer but I don't know if there's a better one.

var p Product
dynamodbattribute.UnmarshalMap(out.Items[0], &p)
b, _ := json.Marshal(p)
fmt.Println(string(b))

First I unmarshal the item from DynamoDB to a Go Struct then marshal to JSON. That seems like a lot of work, I would prefer to go from map[string]*AttributeValue directly to a JSON string (without all these NULL values of course)

So if somebody can come up with something more elegant, pls share.

Upvotes: 2

tier1
tier1

Reputation: 6433

You should be able to do this with JSON struct omitempty tags

type Total struct {
    A *ColorGroup`json:",omitempty"`
    B string`json:",omitempty"`
}

Upvotes: 0

Related Questions