Protobuf3's pit

problem description

after protobuf rises from 2 to 3, there is a very annoying pit:

protobuf

related codes

message UserInfo{
    bool IsAuth = 1;
    string Name = 2;
}

if IsAuth is false, it returns {"Name": "xxxx"}
if IsAuth is true, it returns {"IsAuth": true, "Name": "xxxxx"}

.

similar problems and a lot of int32=0,string= "" ignore fields

here comes the problem

We interact with the front end using the missing field jsonrpc, which makes the front end not very friendly to deal with. I wonder if there is any way to solve this problem.

Jun.22,2021

there is a better solution.
the file generated by proto is still best not to modify it, it is reasonable to exist.
you can take a look at this.

var pbMarshaler jsonpb.Marshaler

func init() {
    pbMarshaler = jsonpb.Marshaler{
        EmitDefaults: true,
        OrigName:     true,
        EnumsAsInts:  true,
    }
}

there is a Marshal method to read the pb object to buffer, and the rest is buffer.Bytes ().
this method is very convenient and is recommended.


type Req struct {
    Type       int32  `protobuf:"varint,5,opt,name=type" json:"type,omitempty"`
}

Delete the omitempty of the generated pb.go file

type Req struct {
    Type       int32  `protobuf:"varint,5,opt,name=type" json:"type"`
}

so OK


cannot be achieved directly in the proto protocol definition file


solve your problem in a word.

 Google.Protobuf.JsonFormatter.Settings.Default.WithFormatDefaultValues(true);
The value false or true in

represents whether to generate a serialized string for the default value. By default, no serialization string is generated.


18 years' question, but if you see it, give a simple answer. This problem occurs because protoc generates code that adds omitempty to json tag , so we use protoc-go-inject-tag .

< H2 > install < / H2 >
go get -u github.com/favadi/protoc-go-inject-tag
< H2 > use < / H2 >
message UserInfo{
    // @inject_tag: json:"is_auth"
    bool IsAuth = 1;
    // @inject_tag: json:"name"
    string Name = 2;
}

generate pb files using protoc

protoc --go_out=. user.proto

run protoc-go-inject-tag

protoc-go-inject-tag -input=./user.pb.go

similarly, you can also use other tag if you want to change it.

Menu