我想使用客户端应用程序请求 JSON 响应并将此响应解组为结构。为了确保结构在使用此包的所有客户端应用程序中保持相同,我想将 JSON 响应定义为 protobuf 消息。我很难将 JSON 解组为 protobuf 生成的结构。


我有以下 JSON 数据:


[

  {

    "name": "C1",

    "type": "docker"

  },

  {

    "name": "C2",

    "type": "docker"

  }

]

我已经像这样建模了我的 protobuf 定义:


syntax = "proto3";

package main;


message Container {

    string name = 1;

    string type = 2;

}


message Containers {

    repeated Container containers = 1;

}

将此模式与结构一起使用通常可以工作,但由于某种原因,使用这些原型定义会导致问题。下面的代码演示了一个工作和一个非工作示例。尽管其中一个版本有效,但我无法使用此解决方案,因为[]*Container不满足proto.Message接口。


package main


import (

    "encoding/json"

    "fmt"

    "strings"


    "github.com/gogo/protobuf/jsonpb"

)


func working(data string) ([]*Container, error) {

    var cs []*Container

    return cs, json.Unmarshal([]byte(data), &cs)

}


func notWorking(data string) (*Containers, error) {

    c := &Containers{}

    jsm := jsonpb.Unmarshaler{}

    if err := jsm.Unmarshal(strings.NewReader(data), c); err != nil {

        return nil, err

    }

    return c, nil

}


func main() {

    data := `

[

  {

    "name": "C1",

    "type": "docker"

  },

  {

    "name": "C2",

    "type": "docker"

  }

]`


    w, err := working(data)

    if err != nil {

        panic(err)

    }

    fmt.Print(w)


    nw, err := notWorking(data)

    if err != nil {

        panic(err)

    }

    fmt.Print(nw.Containers)

}

运行它会给出以下输出:


[name:"C1" type:"docker"  name:"C2" type:"docker" ]

panic: json: cannot unmarshal array into Go value of type map[string]json.RawMessage


goroutine 1 [running]:

main.main()

        /Users/example/go/src/github.com/example/example/main.go:46 +0x1ee


Process finished with exit code 2

有没有办法将此 JSON 解组为Containers?或者,使[]*Container满足proto.Message接口?