How to define empty parameter for Protocol Buffers rpc method? - protocol-buffers

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.

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;
}
}

GRPC Service with Generic proto request data in GoLang

I have 3 protos as follow:
1 - record.proto
message Record {
int64 primaryKey = 1;
int64 createdAt = 2;
int64 updatedAt = 3;
}
2 - user.proto
import "record.proto";
message User {
Record record = 31;
string name = 32;
string email = 33;
string password = 34;
}
3 - permissions.proto
import "record.proto";
message Permissions{
Record record = 31;
string permission1= 32;
string permission2= 33;
}
Question1:
Is there a way to implement a grpc server and client in golang that takes specifically Record as request but entertains both later types. i.e User and Permissions.
Something like:
service DatabaseService {
rpc Create(Record) returns (Response);
}
So that I can send grpc client request as both follow:
Create(User) returns (Response);
Create(Permissions) returns (Response);
You can use oneof which allows the client to send either User or Permissions.
Refer https://developers.google.com/protocol-buffers/docs/proto3#oneof
message Request {
oneof request {
User user = 1;
Permissions permissions = 2;
}
}
So client can fill any of them in the request.
service DatabaseService {
rpc Create(Request) returns (Response);
}

oneof CustomType protobuf

I am tyring to replicate python schema code to golang(protobuf). I am stuck in 1 of the condition.
message Type1 {
enum Type{
type1 = 1
}
Type type = 0;
string name = 1;
}
message Type2 {
enum Type{
type2 = 1
}
Type type = 0;
string name = 1;
repeated string value = 2;
}
message Type3 {
enum Type{
time = 1
}
Type type = 0;
string name = 1;
string format = 2;
string value = 3;
}
message Request {
something
something
map<string, oneof_above_defined_types> params = n
}
How do i make sure that map takes only custom types defined above?
I think you'll need to define a new type that includes the oneof type:
message TypeX {
oneof type_oneof {
Type1 type_1 = 1;
Type2 type_2 = 2;
Type3 type_3 = 3;
};
}
message Request {
...
map<string, TypeX> params = n;
}

How do I assign value to a repeated oneof field in a protobuf message?

I have a protobuf message CoverageReport like this:
message Deductible {
double amount = 1;
string currency = 2;
}
message Insurance{
string type = 1;
string policyNumber = 2;
string agreementName = 3;
string appliedTo = 4;
string validFrom = 5;
string validTo = 6;
Deductible deductible = 7;
}
message Warranty {
string type = 1;
string warrantyType = 2;
string agreementName = 3;
string appliedTo = 4;
string validFrom = 5;
string validTo = 6;
}
message Coverage {
oneof item {
Insurance insurance = 1;
Warranty warranty = 2;
}
}
message CoverageReport {
bool coverageAppliance = 1;
repeated Coverage coverages = 2;
}
In my program I'm trying to assign values to a message instance, but I'm not sure how to assign to the oneof field Coverage which should then be appended to Coverages, like this
I get a response from an api, which i unmarshal into the struct CoverageReport which has similar structure to the protobuf. Then i need to create a protobuf message using the values from the struct. But it doesn't seem to work to asssign to the one of field!
type CoverageReport struct {
CoverageAppliance string `json:"coverageAppliance"`
Coverages []struct {
Type string `json:"type"`
PolicyNumber string `json:"policyNumber,omitempty"`
AgreementName string `json:"agreementName"`
AppliedTo string `json:"appliedTo"`
ValidFrom string `json:"validFrom"`
ValidTo string `json:"validTo"`
Deductible struct {
Amount float64 `json:"amount"`
Currency string `json:"currency"`
} `json:"deductible,omitempty"`
WarrantyType string `json:"warrantyType,omitempty"`
} `json:"coverages"`
}
var coveragereport *CoverageReport
err = json.Unmarshal(body, &coveragereport)
var cr *vcsproto.CoverageReport
if coveragereport.CoverageAppliance == "Yes" {
cr.CoverageAppliance = true
}
for _, item := range coveragereport.Coverages {
if item.Type == "Warranty"{
var warranty *vcsproto.Warranty
warranty.Type = item.Type
warranty.WarrantyType = item.WarrantyType
warranty.AgreementName = item.AgreementName
warranty.AppliedTo = item.AppliedTo
warranty.ValidFrom = item.ValidFrom
warranty.ValidTo = item.ValidTo
var coverage *vcsproto.Coverage
coverage.Item.Warranty = warranty
cr.Coverages = append(cr.Coverages, coverage)
} else {
var insurance *vcsproto.Insurance
insurance.Type = item.Type
insurance.PolicyNumber = item.PolicyNumber
insurance.AgreementName = item.AgreementName
insurance.AppliedTo = item.AppliedTo
insurance.ValidFrom = item.ValidFrom
insurance.ValidTo = item.ValidTo.
insurance.Deductible.Currency = item.Deductible.Currency
insurance.Deductible.Amount = item.Deductible.Amount
var coverage *vcsproto.Coverage
coverage.Item.Insurance = Insurance
cr.Coverages = append(cr.Coverages, coverage)
}
}
Take a look in the generated code here.
You do not assign directly to the Warranty nor Insurance subfields, but directly to the Item field. so coverage.Item = {insurance/warranty} should work.
Also note that in your code you're assigning coverage.Item.Insurance = Insurance - you probably meant the second Insurance to be the variable insurance instead.

Resources