It would be useful to see an example of the workflow of using this tool compared with the equivalent workflow while using protoc. That would be a selling point, while "modern" is just a sticking point.
It helps to standardize workflows across a number of different source repositories (all Go based), where a number of different developers had come up with different ad-hoc ways of generating code against protobuf definitions. Since the syntax is Go-derived, it reduces cognitive load for developers when specifying protocol buffer definitions. We understand that it may not be for everyone, but it works for our team.
Check out releases here: https://github.com/gunk/gunk/releases/tag/v0.1.0
Please note this is still extremely early / alpha stage, but we are soliciting feedback on our initial design. We hope to make this project useful to the greater developer community.
type MyEnum int
const (
MYENUMVAL MyEnum = iota
)
It's a philosophical argument, but one should not design a protocol using "oneof". I believe that's a relic from proto2, and I'm not aware of any modern APIs published by Google, that make use of "oneof" in anything but a legacy capacity. Gunk is not for old protobufs, it's for new development. It works with and integrates cleanly with existing protobuf definitions.Neither the syntax nor build process for protocol buffers has ever seemed particularly difficult.
You mentioned something about cognitive load, but even as a Go developer this looks like it would add to my cognitive load. I have to learn/remember this new syntax and learn/remember the (imperfect) ways in which it maps to protocol buffers, etc.
I could really use some concrete examples of the ways this is better.
I’ve watched new devs pick it up in a matter of minutes.
From a safety perspective, tagged union types, which oneofs are, are incredibly useful and really should be used more often.
[0]: https://github.com/googleapis/googleapis/search?q=oneof&unsc...
[1]: I have no idea what this repo actually does, to be honest, but it appears authoritative about something, and appears to be public grpc apis Google exposes.
message Filter {
oneof kind {
Tags tags = 1;
IPRange ipRange = 2;
}
}
With this in place, a client has to check the type of the filter in order to access the actual filter: switch t := f.Kind.(type) {
case *Tags:
// ...
case *IPRange:
// ...
}
Without it, you can get into a situation where it's possible to create invalid combinations: message Filter {
string type = 1;
Tags tags = 2;
IPRange ipRange = 3;
}
Now you can accidentally end up with code like this: f = Filter{}
f.Type = FilterType_Tags
f.IPRange = IPRange{}
or: if f.Type == FilterType_Tags {
useFilter(f.IPRange)
}1. It enhances readability 2. It would be a surprise to you: oneof actually enhances type safety. It is just lacking type system of Go where you cannot express the feature and thus loses type safety.
https://developers.google.com/protocol-buffers/docs/proto3#o...
I think the feeling is that this is the realm of business logic, and a protocol should be simple and fast and not concern itself with the rules part of the underlying service.
Oneof seems to fall under the same concept, where it says "one and only one field from this list" when they can just as easily do that in service or client logic (three fields, documentation and a server response custom written as to the WHY of oneof relationship)
If I lose oneof too, I might as well be using JSON.
Moving to proto3 means putting all your validation in one place, your serialization primitives in one place, and your docs in one place, instead of smattering them all over. It's a lot less error prone and way more maintenance friendly.