Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Protobuf wrapper class serialized as nil #103

Closed
travisofthenorth opened this issue Apr 13, 2020 · 5 comments
Closed

Protobuf wrapper class serialized as nil #103

travisofthenorth opened this issue Apr 13, 2020 · 5 comments
Labels

Comments

@travisofthenorth
Copy link

Please describe the issue

Apologies in advance if this has nothing to do with gruf. I have a pretty straight-forward server/client setup and I'm serializing proto3 objects in the response. I'm seeing a strange issue where an int wrapper object with a value of 0, i.e. <Google::Protobuf::Int32Value: value: 0>, comes over the wire to the client as nil.

How to Reproduce

Serialize a proto object with a property as described in the issue.

What should happen?

The response on the client side should contain <Google::Protobuf::Int32Value: value: 0> for the particular attribute instead of nil

Anything else we should know?

Server:

  • google-protobuf 3.11
  • grpc 1.24
  • gruf 2.8.0
  • Ruby 2.6.3
  • OS: I think it's a debian docker container
@splittingred
Copy link
Member

splittingred commented Apr 13, 2020

Hi @travisofthenorth - fields in Protobuf are always optional - meaning that any unspecified value will always be nil if not passed. This allows you to do proper presence checks, which allow partial updates to happen.

For instance, take a description - field:

message Product {
   uint64 id = 1;
   string name = 2;
   string description = 3;
}

Lets say I wanted to update Product, but didn't want to touch the description. Right now, description is a native string, which means it will always come over as a string. This means if not set by the client, it will come as "". That's problematic for us, as how would the client differentiate between an empty description (a valid value!) and one not passed?

Google provides wrapper types, such as Google::Protobuf::StringValue, to help with this. Lets change our message:

message Product {
   uint64 id = 1;
   google.protobuf.StringValue name = 2;   
   google.protobuf.StringValue description = 3;
}

Now, we can pass either the name or description optionally, and in our code check for nil to see if the client meant to update that field.

So, in other words - this behavior is expected and intentional. Thanks!

@travisofthenorth
Copy link
Author

@splittingred I'm explicitly passing in Google::Protobuf::Int32Value.new(value: 0)

@travisofthenorth
Copy link
Author

travisofthenorth commented Apr 13, 2020

In any case, another one of my clients doesn't seem to have this problem, so it must be something silly like a gem version in the particular client I'm looking at.

Thanks for taking a look, and apologies for the false alarm!

@travisofthenorth
Copy link
Author

If anyone encounters this error again, this was a bug in protobuf fixed here: protocolbuffers/protobuf#7195

@splittingred
Copy link
Member

@travisofthenorth Oh! Interesting, I misunderstood your question then (didn't realize you were asking about the wrapper value vs the main message).

Thanks for linking the protobuf fix. Appreciate it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

2 participants