DeviceID in proto contracts

Currently we use bytes device_id and a custom type for device ids in the proto contracts.

That’s all fine and well on the wire, but bytes does not translate well for consumers of APIs, because users will have no idea how to go from bytes to our magical dash separated “luhnified with a twist” string, which is what everyone actually sees and uses.

I am also not sure this plays well with grpc-gateway if you have REST paths that have bytes embedded as part of URL rules…

Hence for that reason I’d like to change the type of DeviceID to be a string rather than bytes (in Go code).

To not break wire/db compatability, I guess I have to keep it as bytes in bep.proto and lib/db/structs.proto, but I guess I can handle the conversions around those areas and get away with changing it to string everywhere else.

Also, I think changing the type from bytes to string in terms of proto spec is not a breaking change, as they are both wire type 2 which is “variable length data”, it’s just that there would be a lot of complication when going onto the wire, because you’d have to know if the other side expects a string or bytes, to deluhnify stuff before putting it on the wire.

Whats the general feeling for this? Any other ideas how to solve this?

Yeah, so currently the complexity of deciding the (un)serialization format lives in the DeviceID type which does different things depending whether it’s headed for JSON/XML or protobuf binary. And it isn’t at all visible in the protobuf schema side of things what will happen…

At minimum I think it would be reasonable to change bytes to string in the config related proto schemas, better representing what we actually send/receive there. I don’t think it’s a great idea to change the representation in the wire protocol. Human oriented check digits fluff there doesn’t seem to be added value.

In principle we could have bytes/string in the schema and two different Go types backing them, one being the current DeviceID and the other being a StringBackedDeviceID which uses the string representation for “binary” marshalling. To make some potential grpc thing happy. We’d have to have conversion methods to use in real code. It’s not enormously attractive. Or the config-facing things could be just raw string even in Go and we’d have to do conversion on top of that. In the end I guess it’s a matter of what turns out cleanest…