Reusing Message in the same package in multiple files - go

Is there a way to reuse protobuf structs across multiple proto files?
in the client.proto file I have the following
message SingleOperation {
string command = 1;
}
message ClientBatch {
string unique_id = 1;
repeated SingleOperation requests = 2;
int64 sender = 3;
}
Then in network.proto file, I have the following
message MemPool {
int32 sender = 1;
string unique_id = 2;
SingleOperation op = 3;
}
In the network.proto file, I need to reuse the SingleOperation message.
However, I do not see an option to do this.
Does protobuff support some sort of packaging to support struct reuse?

Related

Parse nested (opaque, any-typed) Protobuf message

I have a message envelope:
import "google/protobuf/any.proto";
message Envelope {
string type = 1;
int32 version = 2;
string message_id = 5;
string timestamp = 6;
google.protobuf.Any message = 7;
}
Now, I happen to know that the message is another Protobuf value with the following type:
And a message defined as follows:
message Message {
int32 value = 1;
string name = 2;
}
Is it possible for me to do a one-shot parsing of this combined message? I am thinking that the problem with substituting Any with Message is the field numbering.
Any is just:
message Any {
string type_url = 1;
bytes value = 2;
}
where the value is just the regular payload content. If you know that the type is your Message, then you can use instead
message Envelope {
string type = 1;
int32 version = 2;
string message_id = 5;
string timestamp = 6;
FakeAny message = 7;
}
message FakeAny {
// don't even need to capture the type_url
Message value = 2;
}
message Message {
int32 value = 1;
string name = 2;
}
and it should deserialize directly.

How to represent a mix of enum and oneof in protobuf

I am trying to create a protocol buffer message with fields that are either a message or one of a choice of some constant (like an enum). Something that is logically equivalent to:
message Error {
oneof error_type {
EMPTY_METHOD_NAME = 0
ExecutionError execution_error = 1;
}
message ExecutionError {
string value = 1;
}
}
Essentially, I would like a field that can represent either an error type that is just a name with no fields, or an error type that has fields. How would I do this with protobuf3?
See Enumerations in the Language Guide (proto3)
message Error {
oneof error_type {
Foo foo = 1;
ExecutionError execution_error = 2;
}
enum Foo {
X = 0;
Y = 1;
Z = 2;
}
message ExecutionError {
string value = 1;
}
}

Protocol buffer split oneof message to a different file

I use nanopb and a .proto file that looks like this (simplified):
syntax = "proto3";
message Type1
{
bool a = 1;
}
message Type2
{
int32 b = 1;
}
message Message
{
int32 id = 1;
oneof oneMessage {
Type1 messageType1 = 2;
Type2 messageType2 = 3;
}
}
I now need to split the oneMessage to a different .proto file and import it. I can do something like:
file a.proto:
syntax = "proto3";
import "b.proto"
message Message
{
int32 id = 1;
oneofTypeMessage aMessage = 2;
}
file b.proto
syntax = "proto3";
message Type1
{
bool a = 1;
}
message Type2
{
int32 b = 1;
}
message oneofTypeMessage
{
oneof oneMessage {
Type1 messageType1 = 2;
Type2 messageType2 = 3;
}
}
But this means I can't get to my message types with message.messageType1, triggering lots of changes in the existing source code. How can I split the oneof part to another file without changing the way I access to it?
I've tried declaring Message in both files but it is not permitted.
No. oneMessage is not a message type, and to import something from another file, it must be a message type. Adding a new oneofTypeMessage would add an additional node in the graph, and would not be data-compatible with the original data.
You can move Type1 and Type2, but the oneof must stay as-was; so: this is valid:
file a.proto:
syntax = "proto3";
import "b.proto"
message Message
{
int32 id = 1;
oneof oneMessage {
Type1 messageType1 = 2;
Type2 messageType2 = 3;
}
}
file b.proto:
syntax = "proto3";
message Type1
{
bool a = 1;
}
message Type2
{
int32 b = 1;
}

Modeling a generic / arbitrary structure of properties with Protobuf

Say I'm modeling a Business resource in Protobuf. It represents any generic kind of "Business" - a bakery, a restaurant, a bank, etc...
Concept, in JSON
In JSON I might model the structure as follows:
{
id: "...",
name: "...",
address: "...",
properties: {
type: "...",
...
}
The properties attribute is a different structure for each type of business.
For a bakery it might be:
properties: {
type: 'Bakery',
serves_coffee: true,
gluten_free: true
}
For a bank it might be:
properties: {
type: "Bank",
max_denomination_offered: 100000,
}
Protobuf
The main Business can be modeled as follows in Protobuf:
message Business {
string id = 1;
string name = 2;
string address = 3;
??? properties = 4
}
How do I model a generic Properties message that can have varying shape?
Is there some sort of "generic" object I can use? Or do I have to create BankProperties, BakeryProperties, etc... and add them in as:
Google.Protobuf.WellKnownTypes.Any properties = 4;
Is there an established or well-accepted pattern for this sort of thing?
Thanks!
What will your receiving code do? If it only knows about specific kinds of Business anyway, it would make sense to just list them in the .proto:
message BakeryProperties {
bool serves_coffee = 1;
bool serves_cake = 2;
}
message BankProperties {
int32 max_denomination = 1;
}
message Business {
string id = 1;
string name = 2;
string address = 3;
oneof details {
BakeryProperties bakery = 100;
BankProperties bank = 101;
}
}
That way you get the actual benefits of a schema: any code that knows how do deal with bakeries, deals with them in the same way. If the code doesn't know about the particular type, it can still use the common properties.
But if you are just going to e.g. display the properties, maybe what you want is just a generic key-value mapping:
map<string,string> properties = 10;
or
message Property {
string name = 1;
oneof {
string strvalue = 2;
int32 intvalue = 3;
}
}
repeated Property properties = 10;

How to define empty parameter for Protocol Buffers rpc method?

I have a method that I would like defined called FindAll which requires no parameters. ProtoC is complaining.
Expected type name.
This is for line:
rpc findAll () returns (BenchmarksList);
syntax = "proto3";
package helloWorldGRPC;
service HelloWorldGRPCService {
rpc findById (BenchmarksById) returns (Benchmarks);
rpc findAll () returns (BenchmarksList);
}
message BenchmarksById {
string id = 1;
}
message BenchmarksList {
repeated Benchmarks benchmarks = 1;
}
message Benchmarks {
string trans_id = 1;
string protocol = 2;
string database = 3;
string updated_at = 4;
string created_at = 5;
repeated Action actions = 6;
}
message Action {
string trans_id = 1;
int32 payload_length = 2;
string payload = 3;
string status = 4;
string updated_at = 5;
string created_at = 6;
}
The preferred way is to pass Empty - as tooling may recognize and optimize for that scenario. But in reality, there is nothing "special" about that type and any message - empty or otherwise - will suffice.

Resources