使用 Go 解组 PubSub 请求数据 []bytes

Posted

技术标签:

【中文标题】使用 Go 解组 PubSub 请求数据 []bytes【英文标题】:Unmarshall PubSub Request Data []bytes with Go 【发布时间】:2016-10-01 10:55:43 【问题描述】:

我有一个从 Google PubSub 请求接收数据的端点。根据this repo,对象是这样的:

type pushRequest struct 
    Message struct 
        Attributes map[string]string
        Data       []byte
        ID         string `json:"message_id"`
    
    Subscription string

数据字段的格式一致:

type Data struct 
    Key  string                 `json:"key"`
    Body string                 `json:"body"`
    Meta map[string]interface `json:"meta"`

我可以明显地用这样的方式解组 JSON 请求:

f := &pushRequest
json.Unmarshal(msg, &f)

剩下的是 []bytes 字段。根据文档,我可以做这样的事情来转换为字符串

messages = append(messages, string(f.Message.Data))

这没有帮助,因为我需要它作为一个结构。

我可以再次解组数组:

var m Data
json.Unmarshal(f.Message.Data, &m)

已尝试将 pushRequest 结构中的字段类型更改为 Data,但未成功。空白...

有没有一种方法可以一次性打开包装?做两次似乎很荒谬。

如果很明显,我就是看不到!

【问题讨论】:

你能显示你试图解组的 json 吗? 您是否尝试在Message struct 中嵌入Data struct?或者如果是子文档,尝试将Data字段的类型从[]byte更改为Data struct 我确实尝试过,但没有成功。这让我很困惑 【参考方案1】:

这是我的云函数中的一个 sn-p,它用作发布/订阅推送端点。关键是您首先必须使用PushRequest 结构对主体进行解码。接下来,您可以将消息数据转换为结构。根据documentation,Message中的Data字段是base-64编码的字符串,所以需要先解码。

type PushRequest struct 
    Message      pubsub.PubsubMessage `json:"message"`
    Subscription string               `json:"subscription"`


type Example struct 
    ID string `json:"id" firestore:"id"`


func HTTPEndpoint(w http.ResponseWriter, r *http.Request) 
    var pr common.PushRequest
    if err := json.NewDecoder(r.Body).Decode(&pr); err != nil 
        log.Fatalf("Could not decode body: %v", err)
        return
    

    data, err := base64.StdEncoding.DecodeString(pr.Message.Data)
    if err != nil 
        log.Fatalf("Base64: %v", err)
        return
    

    var example Example
    if err := json.Unmarshal(data, &example); err != nil 
        log.Fatalf("Json: %v", err)
        return
    

    // Do something useful with the struct

【讨论】:

【参考方案2】:
decoder := json.NewDecoder(r.Body)
psmsg := &PushRequest
decoderErr := decoder.Decode(&psmsg)

if decoderErr != nil 
    // Error... 
    return


data := Data
unmarshalErr := json.Unmarshal([]byte(string(psmsg.Message.Data)), &data)

if unmarshalErr != nil 
    // Error...
    return

【讨论】:

以上是关于使用 Go 解组 PubSub 请求数据 []bytes的主要内容,如果未能解决你的问题,请参考以下文章

Pubsub.pull 请求无法正常工作 - 去吧

json 错误,无法将对象解组为 Go 值

部分 JSON 在 Go 中解组为地图

部分JSON解组到Go中的地图中

json:无法将字符串解组为 MyMap.map 类型的 Go 值

如何编组/解组在 Go 中有两种不同格式的通用 JSON 和 BSON 键/字段?