I'm struggling with Golang Protobuf APIv2.
I'm trying to envelope protobuf messages so that I can invoke functions on a server; functions that aren't known at compile time. Something of the form:
syntax = "proto3";
package p;
import "google/protobuf/any.proto";
option go_package = "...";
message FunctionRequest {
string name = 1;
google.protobuf.Any parameters = 3;
}
message FunctionResponse {
google.protobuf.Any result = 1;
string error = 2;
}
I'm aiming to be generic in using protobufs to define the functions rather than using e.g. Go structs directly.
The Google SDK is complex and I've been unable to find examples.
E.g.
syntax = "proto3";
package e;
option go_package = "...";
service Adder {
rpc add(AdderRequest) returns (AdderResponse) {};
}
message AdderRequest {
int32 a = 1;
int32 b = 2;
}
message AdderResponse {
int32 result = 1;
}
IIUC this raw text file isn't useful directly and needs to be converted to a descriptor file:
protoc \
--proto_path=./protos \
--descriptor_set_out=descriptor.pb \
protos/adder.proto
I assumed (evidently incorrectly) that I could then read this in and unmarshal it to descriptorpb.FileDescriptorProto
:
b, err := ioutil.ReadFile("/path/to/descriptor.pb")
if err != nil {
log.Fatal(err)
}
fdProto := &descriptorpb.FileDescriptorProto{}
proto.Unmarshal(b, fdProto)
Question: How should I be doing this?
Assuming that the client will originate calls for services like Adder
above, the server will need some to be able to unmarshal pbany.Any
parameters into the correct type, invoke the function and reverse the process for the result.
Bonus questions:
- Will the SDK require me to use
protoregistry
to manage these incoming types? Or is there a simpler way? The invocation will include the function and the types for the parameters and result so, it should always be possible to marshal messages on-the-fly. - Any examples using
protoregistry
? I'm confused by the seemingly disjointedFiles
andTypes