google.protobuf.Empty 对向后兼容有危险吗?
Is google.protobuf.Empty dangerous for backwards compatibility?
google.protobuf.Empty
的 spec 状态:
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.
我一直在内部提倡使用空消息包装器来代替,以保持向后兼容性。例如,假设我们有一个 FooService
:
service Foo {
rpc List(google.protobuf.Empty) returns (ListResponse) {}
}
message ListResponse {
repeated Foo results = 1;
}
message Foo {...}
如果将来我们需要为这个列表请求添加分页,我们需要引入一个请求包装器:
message ListRequest {
int limit = 1;
int offset = 2;
}
然后更新rpc签名:
rpc List(ListRequest) returns (ListResponse) {}
这是一个向后不兼容的更改,还是 protobuf 格式可以优雅地处理这个问题?
有线格式可以很好地处理这个问题。但是,大多数使用 gRPC 存根的代码都会中断,因为类型安全语言会注意到不兼容的类型。
如果您认为您可能 曾经 需要字段,请继续为这种情况制作一条特殊消息,即使它是空的。如有疑问,请执行此操作。如果您有信心 永远不会 需要任何字段("delete" 的响应消息是一个常见的例子),那么使用 Empty
就可以了。
我在 Modifying gRPC Services Over Time 演讲中提到了这个具体案例。提供幻灯片和视频录制。
google.protobuf.Empty
的 spec 状态:
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.
我一直在内部提倡使用空消息包装器来代替,以保持向后兼容性。例如,假设我们有一个 FooService
:
service Foo {
rpc List(google.protobuf.Empty) returns (ListResponse) {}
}
message ListResponse {
repeated Foo results = 1;
}
message Foo {...}
如果将来我们需要为这个列表请求添加分页,我们需要引入一个请求包装器:
message ListRequest {
int limit = 1;
int offset = 2;
}
然后更新rpc签名:
rpc List(ListRequest) returns (ListResponse) {}
这是一个向后不兼容的更改,还是 protobuf 格式可以优雅地处理这个问题?
有线格式可以很好地处理这个问题。但是,大多数使用 gRPC 存根的代码都会中断,因为类型安全语言会注意到不兼容的类型。
如果您认为您可能 曾经 需要字段,请继续为这种情况制作一条特殊消息,即使它是空的。如有疑问,请执行此操作。如果您有信心 永远不会 需要任何字段("delete" 的响应消息是一个常见的例子),那么使用 Empty
就可以了。
我在 Modifying gRPC Services Over Time 演讲中提到了这个具体案例。提供幻灯片和视频录制。