json.Unmarshal and "push" to array of structs

huangapple go评论81阅读模式
英文:

json.Unmarshal and "push" to array of structs

问题

我有一个任务,需要从AWS MSK(在AWS Lambda中)读取记录,并准备一些数据以发送到Facebook。从AWS MSK中的记录是Base64编码的,但是一旦我解码它们,我得到的是JSON字符串。现在我不明白如何将json.Unmarshal(decodedParams)转换为&jsonPayload.Data,而jsonPayload.Data是一个结构体数组。

type Payload struct {
    Data Data `json:"data,required"`
}

type Data []struct{
    Event             string         `json:"event_name,required"`
    EventTime         int            `json:"event_time,required"`
    EventSourceUrl    string         `json:"event_source_url,omitempty,required"`
    EventActionSource string         `json:"action_source,omitempty,required"`
    EventId           int            `json:"event_id,required"`
    UserData          UserDataType   `json:"user_data,required"`
    CustomData        CustomDataType `json:"custom_data,omitempty"`
}

type CustomDataType struct {
    SearchString     string      `json:"search_string,omitempty"`
    Value            json.Number `json:"value,omitempty"`
    Currency         string      `json:"currency,omitempty"`
}
type UserDataType struct {
    IpAddress string `json:"client_ip_address,omitempty,required"`
    UserAgent string `json:"client_user_agent,omitempty,required"`
}

// ProcessEvent function Using AWS Lambda computed event
func ProcessEvent(event events.KafkaEvent) {

    jsonPayload := Payload{}

    for _, mapper := range event.Records {

        for _, record := range mapper {

            // Base64 decode string from MSK Kafka
            decodedParams, err := base64.StdEncoding.DecodeString(record.Value)
            if err != nil {
                log.Fatal("Error decoding fb event params: ", err)
            }

            // json.Unmarshal and push to Data []structs???
            unmErr := json.Unmarshal(decodedParams, &jsonPayload.Data)
            if unmErr != nil {
                fmt.Println("UNMARSHAL ERROR")
                fmt.Println(unmErr)
            }
        }
    }
}

func main() {
    lambda.Start(ProcessEvent)
}

最终的结果应该类似于这个:

{
   "data":[
      {
         "event_name":"Purchase",
         "event_time":1627975460,
         "action_source":"email",
         "user_data":{
            "em":[
               "7b17fb0bd173f625b58636fb796407c22b3d16fc78302d79f0fd30c2fc2fc068"
            ],
            "ph":[
               null
            ]
         },
         "custom_data":{
            "currency":"USD",
            "value":"142.52"
         }
      },
      {
         "event_name":"PageView",
         "event_time":1627975460,
         "action_source":"email"
      }
   ]
}

目前我遇到了错误:

json: cannot unmarshal object into Go value of type main.Data

由于我对GO相当陌生,我想知道我是否走在正确的道路上,以及如何将解码后的JSON字符串推送到Data []struct中?如果您需要任何其他信息,请告诉我,我会提供。谢谢!

英文:

I have a task to read records from AWS MSK (in AWS lambda) and prepare some kind of payload to send it to Facebook. Records from AWS MSK are base64 encoded, but once I decode them, I get JSON string. Now I don't understand how json.Unmarshal(decodedParams) in to &jsonPayload.Data which is array of structs

type Payload struct {
Data Data `json:"data,required"`
}
type Data []struct{
Event             string         `json:"event_name,required"`
EventTime         int            `json:"event_time,required"`
EventSourceUrl    string         `json:"event_source_url,omitempty,required"`
EventActionSource string         `json:"action_source,omitempty,required"`
EventId           int            `json:"event_id,required"`
UserData          UserDataType   `json:"user_data,required"`
CustomData        CustomDataType `json:"custom_data,omitempty"`
}
type CustomDataType struct {
SearchString     string      `json:"search_string,omitempty"`
Value            json.Number `json:"value,omitempty"`
Currency         string      `json:"currency,omitempty"`
}
type UserDataType struct {
IpAddress string `json:"client_ip_address,omitempty,required"`
UserAgent string `json:"client_user_agent,omitempty,required"`
}
// ProcessEvent function Using AWS Lambda computed event
func ProcessEvent(event events.KafkaEvent) {
jsonPayload := Payload{}
for _, mapper := range event.Records {
for _, record := range mapper {
// Base64 decode string from MSK Kafka
decodedParams, err := base64.StdEncoding.DecodeString(record.Value)
if err != nil {
log.Fatal("Error decoding fb event params: ", err)
}
// json.Unmarshal and push to Data []structs???
unmErr := json.Unmarshal(decodedParams, &jsonPayload.Data)
if unmErr != nil {
fmt.Println("UNMARSHAL ERROR")
fmt.Println(unmErr)
}
}
}
}
func main() {
lambda.Start(ProcessEvent)
}

End result of payload should be similar to this one

{
"data":[
{
"event_name":"Purchase",
"event_time":1627975460,
"action_source":"email",
"user_data":{
"em":[
"7b17fb0bd173f625b58636fb796407c22b3d16fc78302d79f0fd30c2fc2fc068"
],
"ph":[
null
]
},
"custom_data":{
"currency":"USD",
"value":"142.52"
}
},
{
"event_name":"PageView",
"event_time":1627975460,
"action_source":"email"
}
]
}

Currently I'm getting error

json: cannot unmarshal object into Go value of type main.Data

Since I'm fairly new with GO I wonder if I'm on the right path and how to push decoded json string in to Data []struct? If you need any additional informations, please let me know and I will provide. Thank you!

答案1

得分: 2

每个event.Records的迭代很可能会覆盖你所拥有的内容,更多的尝试将.Data想象成[]data的切片。

type data struct {
    Event             string         `json:"event_name,required"`
    EventTime         int            `json:"event_time,required"`
    EventSourceUrl    string         `json:"event_source_url,omitempty,required"`
    EventActionSource string         `json:"action_source,omitempty,required"`
    EventId           int            `json:"event_id,required"`
    UserData          UserDataType   `json:"user_data,required"`
    CustomData        CustomDataType `json:"custom_data,omitempty"`
}

type Data []data

因此,你将拥有一个unmarshal并将小的data结构体推送到Data切片的代码,类似于以下示例。

var d data
unmErr := json.Unmarshal(decodedParams, &d)
if unmErr != nil {
    fmt.Println("UNMARSHAL ERROR")
    fmt.Println(unmErr)
}

jsonPayload.Data = append(jsonPayload.Data, d)
英文:

Every single iteration of event.Records is likely to overwrite whatever you have the, more of that try to imagine .Data as slice of []data

type data struct {
Event             string         `json:"event_name,required"`
EventTime         int            `json:"event_time,required"`
EventSourceUrl    string         `json:"event_source_url,omitempty,required"`
EventActionSource string         `json:"action_source,omitempty,required"`
EventId           int            `json:"event_id,required"`
UserData          UserDataType   `json:"user_data,required"`
CustomData        CustomDataType `json:"custom_data,omitempty"`
}
type Data []data

So you will have code that unmarshal and push to Data slice small data struct, similar to this.

var d data
unmErr := json.Unmarshal(decodedParams, &d)
if unmErr != nil {
fmt.Println("UNMARSHAL ERROR")
fmt.Println(unmErr)
}
jsonPayload.Data = append(jsonPayload.Data, d) 

huangapple
  • 本文由 发表于 2021年8月3日 15:29:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/68631976.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定