Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is google.protobuf.Empty dangerous for backwards compatibility?

Tags:

The spec for google.protobuf.Empty states:

A generic empty message that you can re-use to avoid defining duplicated empty messages in your APIs. A typical example is to use it as the request or the response type of an API method.

I've been advocating internally to use an empty message wrapper instead, to preserve backwards compatibility. For instance, let's say we have a FooService:

service Foo {
    rpc List(google.protobuf.Empty) returns (ListResponse) {}
}

message ListResponse {
    repeated Foo results = 1;
}

message Foo {...}

If in the future we need to add paging to this list request, we'd need to introduce a request wrapper:

message ListRequest {
    int limit = 1;
    int offset = 2;
}

and then update the rpc signature:

rpc List(ListRequest) returns (ListResponse) {}

Is this a backwards-incompatible change, or can the protobuf format handle this gracefully?

like image 408
DMac the Destroyer Avatar asked Jun 22 '18 18:06

DMac the Destroyer


People also ask

Is protobuf backwards compatible?

Protocol buffers provide a language-neutral, platform-neutral, extensible mechanism for serializing structured data in a forward-compatible and backward-compatible way.

Why is protobuf backwards compatible?

It can accept input crafted by later versions of protobuf. The sender is backward compatible because it's creating output that can be consumed by earlier versions. So long as you're careful about when and how you change and remove fields, your protobuf will be forward and backward compatible.

What is Google protobuf empty?

protobuf. Empty states: A generic empty message that you can re-use to avoid defining duplicated empty messages in your APIs. A typical example is to use it as the request or the response type of an API method.

Can protobuf fields be null?

Protobuf treats strings as primitive types and therefore they can not be null. Instead of checking if the string is not null use standard libraries, like apache commons, to check if the string is not blank. This is clear that the value will be inserted if the value is not blank.


1 Answers

The wire format handles this gracefully. However, most code using the gRPC stubs will break as type-safe languages will notice the incompatible types.

If you think you may ever need fields, go ahead and make a special message for that case, even if it is empty. If in doubt, do it. If you are confident you will never need any fields (the response message of "delete" is a common example), then using Empty is fine.

I mentioned this specific case in my Modifying gRPC Services Over Time talk. Slides and video recording are available.

like image 78
Eric Anderson Avatar answered Sep 16 '22 12:09

Eric Anderson