Я хотел бы получить ответ 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
?