Given the following proto, and assuming we aren't looking to make updates unless absolutely necessary:
message MyMessage {
map<string, string> data = 1
}
On the Go backend, I'm intending on reading data in the following way:
myAttr, err := myMessage.Data["my_attr"]; err != nil {
// do stuff
}
On our typescript/graphql layer, how should I input this "my_attr"
key? Should it be...
myMessage: MyMessage = {
data: {
myAttr: "hello",
},
}
Or should it be
myMessage: MyMessage = {
data: {
"my_attr": "hello",
},
}
And likewise, is there any issue on the Go backend side?
There is no conversion.
Map keys are typed by the Protocol Buffer definition.
In your example, the data
map's keys and values are string
.
You're confusing the conversion that applies to Message|field names (e.g. data
itself) which is converted to Data
and would be converted from my_data
to MyData
in protoc-compiled e.g. Go sources.
Conversion ensures idiomatic code generation between languages that use different behavior than Protocol Buffers' PascalCased Message and snake_cased field names.
Whatever value you provide for the keys and values will remain unchanged.
package main
import (
"log/slog"
"os"
pb "path/to/protos"
"google.golang.org/protobuf/encoding/protojson"
)
const (
key string = "my_attr"
)
func main() {
myMessage := &pb.MyMessage{
Data: map[string]string{key: "hello"},
}
slog.Info("Output", "MyMessage", myMessage)
myAttr, ok := myMessage.Data[key]
if ok {
slog.Info("Output", key, myAttr)
}
j, err := protojson.Marshal(myMessage)
if err != nil {
slog.Error("unable to marshal myMessage", "err", err)
os.Exit(1)
}
slog.Info("Output", "JSON", string(j))
}
Yields: `
Output MyMessage="data:{key:\"my_attr\" value:\"hello\"}"
Output JSON="{\"data\":{\"my_attr\":\"hello\"}}"
NOTE: When accessing map values with a 2-value assignment, the second value is a Boolean (not type error
and conventionally ok
) indicating whether the key exists in the map.