我正在使用Protobuf.js
用于Node,似乎proto3的Any
字段类型为not supported yet。
该模块的作者建议手动定义Any
,如下所示。
syntax = "proto3";
package google.protobuf;
message Any {
string type_url = 1;
bytes value = 2;
}
但是,我不清楚在那之后我应该做些什么。我编写了一个成功使用变通方法的最小脚本:
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);
};
// Pack and create a response
const sampleA = new SampleA({fieldA: 'testa'});
const sampleB = new SampleA({fieldA: 'testa'});
const response = new Response({
id: '1234',
samples: [pack(sampleA), pack(sampleB)]
});
// Unpack
const samples = response.samples.map((sample) => {
return unpack(sample);
});
这有效,我回到了我的预期。但是,我有几个问题:
是否有更好的方法来获取构建type_url的消息的全名。我在我的代码中使用了.toString(),但我看了一下其他语言的实现,并且消息似乎有一些名称的getter。
编码和解码Any消息时,我应该使用.encode和.decode还是有更好的方法?