I've spoken to a few people about this issue, but haven't found any concrete answers. I've figured surely someone else has come across this problem before?
I have structs which are used to bind data to mgo/mongodb calls. Currently, I'm calling data from MongoDB, binding it to a struct, such as...
// Item -
type Item struct {
ID bson.ObjectId `json:"id"`
Name string `json:"name" bson:"name"`
Description string `json:"description" bson:"description"`
Prices []Price `json:"prices" bson:"prices"`
}
I then have a protobuf definition that matches these structs, trouble is to use the generated code, I have to manually do things like...
item := &pb.Item{
Id: itemModel.ID.String(),
Name: itemModel.Name,
Description: itemModel.Description,
Prices: convertPrices(itemModel.Prices),
}
And have functions to convert all embedded structs. Which is incredibly tedious and not great performance wise.
So are there any short cuts or plugins to be able to either use generated code for other purposes, such as database entities, or to somehow marshal between the two types?
Here's a Stack Overflow link with more details: https://stackoverflow.com/questions/45154825/what-would-be-the-best-approach-to-converting-protoc-generated-structs-from-bson?noredirect=1#comment77278817_45154825
评论:
yami_odymel:
ewanvalentine:Not sure if I get your point or not, but when I was using gRPC in Golang, I treat the gRPC-generated struct like a "payload object" instead of a "model struct" (which means I only use it for transferring the data between client and the server.).
So normally I would make a "convertor function" (like:
toItem(in *pb.Item) out &Item
) for it, when I received the gRPC struct, I convert them into a local struct type.It sounds might be stupid but, hell. You are going to use
Id
instead ofID
with the gRPC-generated struct in Golang when everything other is named asID
. And you can't even add the custom struct tag in.proto
file (which is not recommended by the official), it's a pain for me when there're so many packages that require you to specify the struct tags.
jsoniter:That's exactly what I'm doing at the moment, but because it's a NoSQL database, there's 3 levels of nesting, so I have to write an iterator for each of those maps to convert each entity into the pb format. It just feels totally wrong and like I'm not really getting any benefit of gRPC's performance, if I have to do a bunch of serialisation of my own before it gets serialised into binary!
I wish there was a plugin to just include mongodb friendly tags somehow, or some kind of quick serialise method. Ah well, at least it's not just me, I guess!
ewanvalentine:if protobuf support field tags, will this pain go away?
shovelpost:I believe so, yes. Though there's still the issue of converting the
Id
field name intoID
and the type from string tobson.ObjectId
.
recurrency:I think the way /u/yami_odymel recommends is our best bet. This is also how the upspin team does it.
It is very unfortunate that the protobuf team have decided not to fix the non idiomatic field names like Id.
recurrency:if it's about the struct tags I think gogo/protobuf has an extension for that? https://github.com/gogo/protobuf/
ewanvalentine:exemple: https://github.com/gogo/protobuf/blob/master/test/tags/tags.proto
TheMerovius:Not just that unfortunately, there's converting the Id field to and from
Id string
andID bson.ObjectId
It's pretty trivial, to write your own protoc-plugin, FWIW. If your conversion is sufficiently automatic, it might be worth giving that a try.
