自定义DynamodB umarshal到Golang struct
#aws #serverless #go #dynamodb

将DynamoDB映射分解为像GO结构一样强烈键入的内容的简短帖子。如果您想直接跳到某个代码,这里是github gist

那么,什么是“ Unmarshalling”?这是拿出一个数据并将其转换为另一个数据的行为。例如,当我们将数据存储在DynamoDB中时,本机数据类型之一是“映射”。地图实际上不过是字典/钥匙值类型查找。将字典视为具有密钥和后续值的数据结构。键必须是唯一的。以这些数据为例


{
  "Roles": {
    "1": {
      "name": "Role number 1",
      "id": 1
    },
    "2": {
      "name": "Role number 2",
      "id": 2
    }
  },
  "SK": "ROLE#1234",
  "PK": "USERPROFILE#1000130",
  "EntityType": "UserRole"
}

角色属性是一张地图。它包含["1"]["2"]的键。然后,每个键中的每个键都包含另一个地图。这些看起来很像JSON对象,并且出于各种意图和目的,可以这样认为它们是可以的。

因此,使用这些数据,我们如何将其纳入看起来像这样的东西

type UserRole struct {
    EntityType string `dynamodbav:"EntityType"`
    Roles      []Role `dynamodbav:"Roles"`
}

type Role struct {
    Id   int
    Name string
}</pre>

UserRole struct具有EntyType属性以及具有角色结构的角色切片。每个字段还具有将它们描述为在Dyanamodb属性值中用与列名相对应的名称表示的事物。随时阅读更多here

开始摘要的第一步是构建UserRole并将其解散。


ur := &amp;UserRole{}
_ = dynamodbattribute.UnmarshalMap(i, ur)</pre>

默认情况下,这实际上只会删除GO库知道如何处理的字段。与使用JSON UMARSHALLING合作时非常相似,可以使用DynamoDB
进行同样的操作

func (ur *UserRole) UnmarshalDynamoDBAttributeValue(value *dynamodb.AttributeValue) error {
    for k, kv := range value.M {
        if k == "EntityType" {
            ur.EntityType = *kv.S
        } else if k == "Roles" {
            for _, nkv := range kv.M {
                r := &amp;Role{}
                err := dynamodbattribute.UnmarshalMap(nkv.M, r)
                if err != nil {
                    return err
                }
                ur.Roles = append(ur.Roles, *r)
            }
        }
    }
    return nil
}

请注意,您可以旋转传递的属性值的密钥/值对。对于每个键,您可以确定内部的对象类型。例如,EntityType字段是一个字符串。这很简单。

但是有了Roles字段,还有另一张地图要处理。再一次,只需汇总该变量,然后将自定义步骤一层进一步

func (r *Role) UnmarshalDynamoDBAttributeValue(value *dynamodb.AttributeValue) error {
    for k, kv := range value.M {
        if k == "id" {
            v, _ := strconv.ParseInt(*kv.N, 10, 32)
            r.Id = int(v)
        } else if k == "name" {
            r.Name = *kv.S
        }
    }

    return nil
}

就在那里。来自DynamoDB地图的Umarshalled自定义类型。它也没有太多,但是这种超级强大,因为您可以意识到使用自定义代码存储在GO结构中的任何类型的数据。

希望这很有帮助!