解组具有更改的嵌入类型的消息时出现未知字段错误
Unknown field error when unmarshaling a message with changed embedded type
给出这样的原型:
message Request {
uint64 account_id = 1;
message Foo{
uint64 foo_id = 1;
}
repeated Foo foos = 2;
当我添加一个名为 bar_id
的字段时
message Request {
uint64 account_id = 1;
message Foo{
uint64 foo_id = 1;
uint64 bar_id = 2;
}
repeated Foo foos = 2;
通过 proto.UnmarshalText(msg, request)
使用旧 client
反序列化时出现错误。错误是 unknown field name "bar_id" in serviceA.Request_Foo
.
我知道 proto-3 中的 unknown field
处理有很多变化,但这不是预期的,因为它似乎违反了前向兼容性(新服务器向旧客户端发送请求)。这与使用嵌入式类型有关吗?在不强制客户端更新的情况下更新服务器的最佳方法是什么?
您似乎在使用 github.com/golang/protobuf which is deprecated. Use google.golang.org/protobuf/encoding/prototext
UPD:使用DiscardUnknown
(prototext.UnmarshalOptions{DiscardUnknown: true}).Unmarshal(b, msg)
pb.proto:
syntax = "proto3";
// protoc --go_out=. *.proto
package pb;
option go_package = "./pb";
message RequestOld {
uint64 account_id = 1;
message Foo{
uint64 foo_id = 1;
}
repeated Foo foos = 2;
}
message RequestNew {
uint64 account_id = 1;
message Foo{
uint64 foo_id = 1;
uint64 bar_id = 2;
}
repeated Foo foos = 2;
}
函数:
import "google.golang.org/protobuf/encoding/prototext"
// marshal old message
msgOld := &pb.RequestOld{
AccountId: 1,
Foos: []*pb.RequestOld_Foo{
{
FooId: 2,
},
},
}
log.Println("old:", msgOld.String())
bOld, err := prototext.Marshal(msgOld)
if err != nil {
panic(err)
}
// unmarshal to new message
msgNew := &pb.RequestNew{}
if err := prototext.Unmarshal(bOld, msgNew); err != nil {
panic(err)
}
log.Println("new:", msgNew.String())
输出:
2021/04/07 old: account_id:1 foos:{foo_id:2}
2021/04/07 new: account_id:1 foos:{foo_id:2}
给出这样的原型:
message Request {
uint64 account_id = 1;
message Foo{
uint64 foo_id = 1;
}
repeated Foo foos = 2;
当我添加一个名为 bar_id
message Request {
uint64 account_id = 1;
message Foo{
uint64 foo_id = 1;
uint64 bar_id = 2;
}
repeated Foo foos = 2;
通过 proto.UnmarshalText(msg, request)
使用旧 client
反序列化时出现错误。错误是 unknown field name "bar_id" in serviceA.Request_Foo
.
我知道 proto-3 中的 unknown field
处理有很多变化,但这不是预期的,因为它似乎违反了前向兼容性(新服务器向旧客户端发送请求)。这与使用嵌入式类型有关吗?在不强制客户端更新的情况下更新服务器的最佳方法是什么?
您似乎在使用 github.com/golang/protobuf which is deprecated. Use google.golang.org/protobuf/encoding/prototext
UPD:使用DiscardUnknown
(prototext.UnmarshalOptions{DiscardUnknown: true}).Unmarshal(b, msg)
pb.proto:
syntax = "proto3";
// protoc --go_out=. *.proto
package pb;
option go_package = "./pb";
message RequestOld {
uint64 account_id = 1;
message Foo{
uint64 foo_id = 1;
}
repeated Foo foos = 2;
}
message RequestNew {
uint64 account_id = 1;
message Foo{
uint64 foo_id = 1;
uint64 bar_id = 2;
}
repeated Foo foos = 2;
}
函数:
import "google.golang.org/protobuf/encoding/prototext"
// marshal old message
msgOld := &pb.RequestOld{
AccountId: 1,
Foos: []*pb.RequestOld_Foo{
{
FooId: 2,
},
},
}
log.Println("old:", msgOld.String())
bOld, err := prototext.Marshal(msgOld)
if err != nil {
panic(err)
}
// unmarshal to new message
msgNew := &pb.RequestNew{}
if err := prototext.Unmarshal(bOld, msgNew); err != nil {
panic(err)
}
log.Println("new:", msgNew.String())
输出:
2021/04/07 old: account_id:1 foos:{foo_id:2}
2021/04/07 new: account_id:1 foos:{foo_id:2}