Home  >  Article  >  Backend Development  >  gRPC does not return a boolean value if the value is false

gRPC does not return a boolean value if the value is false

PHPz
PHPzforward
2024-02-10 09:30:09460browse

如果值为 false,gRPC 不会返回布尔值

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.

Question content

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}]}

Solution

This is by design and to improve efficiency.

The "zero" value of

bool 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:

  • It is possible to remove the 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;
  • If using grpc-gateway, please override it at runtime, for example
gwmux := runtime.newservemux(runtime.withmarshaleroption(runtime.mimewildcard, &runtime.jsonpb{origname: true, emitdefaults: true}))
  • Or, if you export json yourself, instead of using the standard library (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!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete