Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

An easier way of setting nested properties values in Grpc generated java code

We are using Grpc with our java apps and we have a nested object defined in protobuff.

example of the proto:

message Person {
  string name = 1;
  Child child = 2; 
}

message Child {
  string name = 1;
  Hobby hobbies = 2;
}

message Hobby {
  string name = 1;
  string reason = 2;
}

When I want to update the reason for the child's hobby I have to do something like:

person.toBuilder()
.setChild(
    person.getChild.toBuilder()
        .setHobby(
            person.getChild().getHobby().toBuilder()
                .setReason("new reason")
                .build()
        )
        .build()
)
.build()

The code above is not the nicest and my question is if there is any better way to accomplish the same?

like image 648
hen shalom Avatar asked Aug 26 '26 05:08

hen shalom


1 Answers

TL;DR

Person.Builder builder = person.toBuilder();
builder.getChildBuilder().getHobbyBuilder().setReason("new reason");
Person personWithUpdatedReason = builder.build();

Details: Better way is subjective, what are you expectations? I believe, something along the lines of:

person.getChild().getHobby().setReason("new reason");

If that's the case, you'd want the object to be mutable, which, depending upon the context, may not be a good thing.

Another example:

Hobby newHobby = person.getChild().getHobby().toBuilder().setReason("new reason").build();
Child newChild = person.getChild().toBuilder().setHobby(newHobby).toBuild();
Person newPerson = person.toBuilder().setChild(newChild).toBuild();

return newPerson;

This is better if only you don't like your code to have multi-level nesting.

Unfortunately, I don't think I helped you, rather interested to know what you/others think of this.

I read a bit more on this, and the official docs do suggest a better way: https://developers.google.com/protocol-buffers/docs/reference/java-generated?csw=1#sub-builders

So you can write you code something like this:

Person.Builder builder = person.toBuilder();
builder.getChildBuilder().getHobbyBuilder().setReason("new reason");
Person personWithUpdatedReason = builder.build();
like image 129
ryuzaki Avatar answered Aug 27 '26 18:08

ryuzaki



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!