I use Protobuf.jsfor Node and it seems that the field type Anyfrom proto3 is not yet supported .
The author of the module suggests manually defining Any, as shown below.
syntax = "proto3";
package google.protobuf;
message Any {
string type_url = 1;
bytes value = 2;
}
However, it is not very clear to me what I should do after this. I wrote a minimal script that successfully uses a workaround:
myservice.proto
syntax = "proto3";
package myservice;
message Any {
string type_url = 1;
bytes value = 2;
}
message Request {
string id = 1;
}
message SampleA {
string fieldA = 1;
}
message SampleB {
string fieldB = 1;
}
message Response {
string id = 1;
repeated Any samples = 2;
}
service MyService {
rpc Get (Request) returns (Response);
}
samples.js
const ProtoBuf = require('protobufjs');
const builder = ProtoBuf.loadProtoFile('./myservice.proto');
const Any = builder.build('Any');
const SampleA = builder.build('SampleA');
const SampleB = builder.build('SampleB');
const Response = builder.build('Response');
const pack = (message, prefix) => {
return new Any({
type_url: path.join((prefix || ''), message.toString()),
value: message.encode()
});
};
const unpack = (message) => {
const b = builder.build(message.type_url.split('.')[1]);
return b.decode(message.value);
};
const sampleA = new SampleA({fieldA: 'testa'});
const sampleB = new SampleA({fieldA: 'testa'});
const response = new Response({
id: '1234',
samples: [pack(sampleA), pack(sampleB)]
});
const samples = response.samples.map((sample) => {
return unpack(sample);
});
This works, and I return what I expected. However, I have a few questions:
Is there a better way to get the full name of the message for building type_url. I used .toString () in my code, but I looked at implementations of other languages, and the posts seem to have some kind of getter for the name.
.encode .decode ?