What would be the best way to re-use the generated protobuf structs for other purposes?

blov · 2017-07-18 23:00:06 · 845 次点击    
这是一个分享于 2017-07-18 23:00:06 的资源,其中的信息可能已经有所发展或是发生改变。

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:

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 of ID with the gRPC-generated struct in Golang when everything other is named as ID. 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.

ewanvalentine:

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!

jsoniter:

if protobuf support field tags, will this pain go away?

ewanvalentine:

I believe so, yes. Though there's still the issue of converting the Id field name into ID and the type from string to bson.ObjectId.

shovelpost:

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/

recurrency:

exemple: https://github.com/gogo/protobuf/blob/master/test/tags/tags.proto

ewanvalentine:

Not just that unfortunately, there's converting the Id field to and from Id string and ID bson.ObjectId

TheMerovius:

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.


入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

845 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传