My Proto file looks something like this:
message Test {
Service services = 1;
}
message Service {
string command = 1;
string root = 2;
}
This .proto can support a json like this:
{
"services": {
"command": "command2",
"root": "/"
},
}
But, I want to manage a json that looks like this:
{
"services": {
"service1": {
"command": "command1",
"root": "/"
},
"service2": {
"command": "command2",
"root": "/"
},
},
}
So, here all the services will have common structure but the key name will vary (i.e. "service1"
, "service2"
)
Now, I want to read the data from test.json and unmarshal it:
var test *Test
err := json.Unmarshal([]byte(file), &test)
What changes should I do in the .proto
so that I can unmarshall this json successfully?
CodePudding user response:
Use a proto map:
message Test {
map<string, Service> services = 1;
}
message Service {
string command = 1;
string root = 2;
}
The proto map is compiled to map[K]V
in Go, so map[string]*Service
in this case, which is the recommended way to model JSON with arbitrary keys.
This will give the following output:
services:{key:"service1" value:{command:"command1" root:"/"}} services:{key:"service2" value:{command:"command2" root:"/"}}
Example program:
package main
import (
"encoding/json"
"example.com/pb"
"fmt"
)
const file = `{
"services": {
"service1": {
"command": "command1",
"root": "/"
},
"service2": {
"command": "command2",
"root": "/"
}
}
}
`
func main() {
test := &pb.Test{}
err := json.Unmarshal([]byte(file), test)
if err != nil {
panic(err)
}
fmt.Println(test)
}