Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gRPC not returning boolean if value is false

Tags:

go

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

I have one record in the db | id | title | is_completed | |-|-|-| | 1 | aaa | false |

the function above returns {"todos": [{"id": "1", "title": "aaa"}]} but once I change the is_completed to true the result is correct {"todos": [{"id": "1", "title": "aaa", "isCompleted": true}]}

like image 226
Sevy Avatar asked Dec 14 '25 13:12

Sevy


1 Answers

This is by design and for efficiency.

The "zero" value for a bool is false - so when initializing your protobuf struct with a false value, the field does not need to be explicitly stated when using the standard libary's encoding/json unmarshaler. On the encoding end, if the field's JSON tag includes an omitempty qualifier, the standard libary's encoding/json marshaler will remove any zero values - which is what you are seeing. You will see the same behavior with the Title string field if it was "" (i.e. the zero value of a string).

Looking at your generated code (*.pb.go) the struct's bool field definition will look something like this:

type Todo struct {
    // ...
    IsCompleted  bool  `protobuf:"varint,5,opt,name=is_complete,proto3" json:"is_complete,omitempty"`
}

So the json:"...,omitempty" instructs the encoding/json marshaler to omit any zero values during marshalling with tags like theses.

If you want to override this behavior:

  • one could remove the omitempty directive from your generated code (not recommended - as edits would need to be managed over the lifecycle of development). But if you must, refer to this answer;
  • if using grpc-gateway, override this at runtime e.g.
gwmux := runtime.NewServeMux(runtime.WithMarshalerOption(runtime.MIMEWildcard, &runtime.JSONPb{OrigName: true, EmitDefaults: true}))
  • or if exporting the JSON yourself, instead of using the standard library (encoding/json) use the JSON marshaler from this package "google.golang.org/protobuf/encoding/protojson":
protojson.Marshaler{EmitDefaults: true}.Marshal(w, resp)

as outlined in this answer.

like image 194
colm.anseo Avatar answered Dec 16 '25 05:12

colm.anseo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!