php小编百草在介绍gRPC的使用时指出,如果在gRPC请求中,指定的值为false,那么gRPC将不会返回布尔值。这意味着在使用gRPC时,我们需要注意如何处理返回值,以免造成混淆和错误。了解这个细节将帮助我们更好地理解和应用gRPC的功能,提高我们的编程效率和代码质量。让我们一起深入研究gRPC的更多特性和用法,为我们的项目带来更好的性能和扩展性。
问题内容
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;
}
}
我在数据库中有一条记录 |编号 |标题 |已完成 | |-|-|-| | 1 |啊啊|假|
上面的函数返回 {"todos": [{"id": "1", "title": "aaa"}]}
但一旦我将 is_completed
更改为 true
,结果是正确的 {"todos ": [{"id": "1", "title": "aaa", "iscompleted": true}]}
解决方法
这是设计使然,也是为了提高效率。
bool
的“零”值是 false
- 因此,当使用 false
值初始化 protobuf
结构时,在使用标准库的 encoding/json
解组器时不需要显式声明该字段。在编码端,如果字段的 json 标记包含 omitempty
限定符,则标准库的 encoding/json
封送拆收器将删除任何零值 - 这就是您所看到的。
如果 title
字符串字段是 ""
(即字符串的零值),您将看到相同的行为。
查看生成的代码(*.pb.go
),结构体的 bool
字段定义将如下所示:
type todo struct {
// ...
iscompleted bool `protobuf:"varint,5,opt,name=is_complete,proto3" json:"is_complete,omitempty"`
}
因此 json:"...,omitempty"
指示 encoding/json
封送拆收器在使用这些标签进行封送期间省略任何零值。
如果您想覆盖此行为:
- 可以从生成的代码中删除
omitempty
指令(不推荐 - 因为需要在开发的生命周期中管理编辑)。但如果您必须这样做,请参阅此答案; - 如果使用
grpc-gateway
,请在运行时覆盖它,例如
gwmux := runtime.newservemux(runtime.withmarshaleroption(runtime.mimewildcard, &runtime.jsonpb{origname: true, emitdefaults: true}))
- 或者,如果自己导出 json,则不使用标准库 (
encoding/json
),而是使用此包中的json
封送拆收器"google.golang.org/protobuf/encoding/protojson"
:
protojson.Marshaler{EmitDefaults: true}.Marshal(w, resp)
如此答案中所述。
以上就是如果值为 false,gRPC 不会返回布尔值的详细内容,更多请关注编程网其它相关文章!