猿问

如何从迪纳摩DB的戈朗 SDK 中序列化“最后评估密钥”?

在 Golang 中使用 DynamoDB 时,如果呼叫有更多结果,则会设置 在 上,然后您可以将其传递到下一个呼叫,以便从上次中断的地方继续。queryLastEvaluatedKeyQueryOutputqueryExclusiveStartKey


当价值观留在戈朗时,这很有效。但是,我正在编写分页 API 终结点,因此我想序列化此密钥,以便可以将其作为分页令牌交还给客户端。像这样,哪里是神奇的包,它可以做我想做的事:something


type GetDomainObjectsResponse struct {

  Items     []MyDomainObject `json:"items"`

  NextToken string           `json:"next_token"`

}

  

func GetDomainObjects(w http.ResponseWriter, req *http.Request) {

  // ... parse query params, set up dynamoIn ...


  dynamoIn.ExclusiveStartKey = something.Decode(params.NextToken)


  dynamoOut, _ := db.Query(dynamoIn)


  response := GetDomainObjectsResponse{}

  dynamodbattribute.UnmarshalListOfMaps(dynamoOut.Items, &response.Items)


  response.NextToken := something.Encode(dynamoOut.LastEvaluatedKey)

  

  // ... marshal and write the response ...

}

(请原谅上面的任何拼写错误,这是我快速编写的代码的玩具版本,以隔离问题)


由于我需要支持具有不同搜索模式的多个终结点,因此我希望找到一种生成不依赖于特定搜索关键字的分页标记的方法。


麻烦的是,我还没有找到一种干净而通用的方法来序列化.您可以将其直接封送到JSON(然后例如base64编码以获取令牌),但这样做是不可逆的。 是一个 ,并且是一个接口,因此虽然 json 编码器可以读取它,但它无法写入它。LastEvaluatedKeyLastEvaluatedKeymap[string]types.AttributeValuetypes.AttributeValue


例如,以下代码使用 崩溃。panic: json: cannot unmarshal object into Go value of type types.AttributeValue


lastEvaluatedKey := map[string]types.AttributeValue{

    "year":  &types.AttributeValueMemberN{Value: "1993"},

    "title": &types.AttributeValueMemberS{Value: "Benny & Joon"},

}


bytes, err := json.Marshal(lastEvaluatedKey)

if err != nil {

  panic(err)

}


decoded := map[string]types.AttributeValue{}

err = json.Unmarshal(bytes, &decoded)

if err != nil {

  panic(err)

}

我想要的是一种直接使用迪纳莫DB风格的JSON的方法,就像你在CLI上运行aws动态模型查询时得到的一样。不幸的是,高浪 SDK 不支持此功能。


我想我可以为 AttributeValue 类型编写自己的序列化程序/反序列化程序,但这比这个项目应该付出的努力还要多。


有没有人找到一种通用的方法来做到这一点?


心有法竹
浏览 98回答 1
1回答

凤凰求蛊

好吧,我想通了一些东西。type GetDomainObjectsResponse struct {  Items     []MyDomainObject `json:"items"`  NextToken string           `json:"next_token"`}  func GetDomainObjects(w http.ResponseWriter, req *http.Request) {  // ... parse query params, set up dynamoIn ...  eskMap := map[string]string{}  json.Unmarshal(params.NextToken, &eskMap)  esk, _ = dynamodbattribute.MarshalMap(eskMap)  dynamoIn.ExclusiveStartKey = esk  dynamoOut, _ := db.Query(dynamoIn)  response := GetDomainObjectsResponse{}  dynamodbattribute.UnmarshalListOfMaps(dynamoOut.Items, &response.Items)  lek := map[string]string{}  dynamodbattribute.UnmarshalMap(dynamoOut.LastEvaluatedKey, &lek)  response.NextToken := json.Marshal(lek)    // ... marshal and write the response ...}(再次这是我真正的解决方案匆忙转回玩具问题,所以请原谅任何拼写错误)正如@buraksurdar指出的那样,采取.事实证明,除了具体类型之外,您还可以传入 ,它就可以正常工作。attributevalue.Unmarshalinteface{}map[string]string我相信如果这不是平坦的,这将不起作用,所以这不是一个通用的解决方案[需要引用]。但我的理解是,从调用返回的总是平坦的,所以它适用于这个用例。AttributeValueLastEvaluatedKeyQuery
随时随地看视频慕课网APP

相关分类

Go
我要回答