将带有必填字段的新消息添加到 protobuf v2
Adding a new message with required fields to protobuf v2
说,我有两个版本的原型文件:
version 1.0 - initial version
version 2.0 - adds a new message with required fields
从兼容性的角度来看,这是 proto 文件中的有效更改吗?
恕我直言,因为 v2.0
定义了一个带有必填字段的新消息,它应该会导致向后不兼容,因为如果消息从 v2.0
发送到 v1.0
,v1.0
不会理解它,它不会知道如何解码它。而且由于它被标记为 required
,v1.0
甚至不能忽略它。
Protocol Buffers 不处理消息类型的识别。那部分是在应用程序代码中完成的。
所以这个问题的答案取决于应用程序在收到未知消息时做了什么。它可能会忽略它或引发错误 - 您必须检查代码才能知道。
向现有消息类型添加新的必填字段是一项向后不兼容的更改,因为旧服务器永远不会发送该字段。
添加带有必填字段的全新消息类型是向后兼容的,因为旧服务器根本不会发送该消息。例如,假设我们开始于:
message Old {
required int32 i = 1;
}
然后我们添加一条新消息:
message Old {
required int32 i = 1;
optional New m = 2;
}
message New {
required string s = 1;
}
这是向后兼容的。当旧程序向新程序发送消息时,字段 m
将不存在,这很好,因为它是可选的。仅当 m
本身存在时才需要必填字段 m.s
。
当新程序向旧程序发送消息时,字段m
将被忽略。 required
并不意味着接收者不能忽略它。 required
仅表示要求发件人发送。
请注意,我强烈建议不要使用 required
。 Proto3 删除了 required
,而 Cap'n Proto 一开始就没有它,因为它可能会导致意想不到的问题。 Here's an in-depth discussion I wrote.
(披露:我是 Proto2 和 Cap'n Proto 的作者。)
说,我有两个版本的原型文件:
version 1.0 - initial version
version 2.0 - adds a new message with required fields
从兼容性的角度来看,这是 proto 文件中的有效更改吗?
恕我直言,因为 v2.0
定义了一个带有必填字段的新消息,它应该会导致向后不兼容,因为如果消息从 v2.0
发送到 v1.0
,v1.0
不会理解它,它不会知道如何解码它。而且由于它被标记为 required
,v1.0
甚至不能忽略它。
Protocol Buffers 不处理消息类型的识别。那部分是在应用程序代码中完成的。
所以这个问题的答案取决于应用程序在收到未知消息时做了什么。它可能会忽略它或引发错误 - 您必须检查代码才能知道。
向现有消息类型添加新的必填字段是一项向后不兼容的更改,因为旧服务器永远不会发送该字段。
添加带有必填字段的全新消息类型是向后兼容的,因为旧服务器根本不会发送该消息。例如,假设我们开始于:
message Old {
required int32 i = 1;
}
然后我们添加一条新消息:
message Old {
required int32 i = 1;
optional New m = 2;
}
message New {
required string s = 1;
}
这是向后兼容的。当旧程序向新程序发送消息时,字段 m
将不存在,这很好,因为它是可选的。仅当 m
本身存在时才需要必填字段 m.s
。
当新程序向旧程序发送消息时,字段m
将被忽略。 required
并不意味着接收者不能忽略它。 required
仅表示要求发件人发送。
请注意,我强烈建议不要使用 required
。 Proto3 删除了 required
,而 Cap'n Proto 一开始就没有它,因为它可能会导致意想不到的问题。 Here's an in-depth discussion I wrote.
(披露:我是 Proto2 和 Cap'n Proto 的作者。)