When php editor Baicao introduced the use of gRPC, he pointed out that if the specified value is false in the gRPC request, then gRPC will not return a Boolean value. This means that when using gRPC, we need to pay attention to how return values are handled to avoid confusion and errors. Understanding this detail will help us better understand and apply the functions of gRPC, and improve our programming efficiency and code quality. Let's delve into more features and usage of gRPC to bring better performance and scalability to our projects.
func (m *todoserver) gettodos(ctx context.context, empty *emptypb.empty) (*desc.gettodosresponse, error) { todos, err := m.todoservice.gettodos() if err != nil { return nil, err } todosresp := make([]*desc.gettodosresponse_todo, 0, len(todos)) for _, todo := range todos { todosresp = append(todosresp, &desc.gettodosresponse_todo{ id: todo.id, title: todo.title, iscompleted: todo.iscompleted, }) } return &desc.gettodosresponse{todos: todosresp}, nil }
service TodoService { rpc GetTodos(google.protobuf.Empty) returns (GetTodosResponse) {} } message GetTodosResponse { repeated Todo todos = 1; message Todo { int64 id = 1; string title = 2; bool is_completed = 3; } }
service TodoService { rpc GetTodos(google.protobuf.Empty) returns (GetTodosResponse) {} } message GetTodosResponse { repeated Todo todos = 1; message Todo { int64 id = 1; string title = 2; bool is_completed = 3; } }
I have a record in the database |Number |Title |Completed | |-|-|-| | 1 |Ahhh|False|
The above function returns {"todos": [{"id": "1", "title": "aaa"}]}
But once I change is_completed
is true
, the result is correct{"todos ": [{"id": "1", "title": "aaa", "iscompleted": true}]}
This is by design and to improve efficiency.
The "zero" value ofbool
is false
- so when a protobuf
structure is initialized with a false
value, when using the standard This field does not need to be explicitly declared when using the library's encoding/json
unmarshaller. On the encoding side, if the field's json tag contains the omitempty
qualifier, the standard library's encoding/json
marshaler will remove any zero values - this is what you see of.
You will see the same behavior if the title
string field is ""
(i.e. the zero value of the string).
View the generated code (*.pb.go
), the bool
field definition of the structure will be as follows:
type todo struct { // ... iscompleted bool `protobuf:"varint,5,opt,name=is_complete,proto3" json:"is_complete,omitempty"` }
Thus json:"...,omitempty"
instructs the encoding/json
marshaler to omit any zero values during marshaling using these tags.
If you want to override this behavior:
omitempty
directive from the generated code (not recommended - due to the need to manage editing during the development life cycle). But if you must do this, see this answer;grpc-gateway
, please override it at runtime, for example gwmux := runtime.newservemux(runtime.withmarshaleroption(runtime.mimewildcard, &runtime.jsonpb{origname: true, emitdefaults: true}))
encoding/json
), use the json
marshaler" in this package google.golang.org/protobuf/encoding/protojson"
:protojson.Marshaler{EmitDefaults: true}.Marshal(w, resp)
As mentioned in this answer.
The above is the detailed content of gRPC does not return a boolean value if the value is false. For more information, please follow other related articles on the PHP Chinese website!