availability of 'well known types' in proto3 protocol-buffers - protocol-buffers

I see that StringValue is the message wrapper for a string message, which I attempt to use in:
service SomeService {
// health
rpc HealthCheck(google.protobuf.Empty)
returns (google.protobuf.Empty) {}
// create
rpc CreateSomething(SomeMessageType)
returns (StringValue) {}
}
However, I get a message from protoc like:
somefile.proto:30:14: "StringValue" is not defined.
I'm using proto3 syntax. What am I missing?

OK.
I needed:import "google/protobuf/wrappers.proto";
and, to use the fully qualified google.protobuf.StringValue

Related

Is there known way to add new syntax features to Protobuf?

Protobuf provides service keyword that defines rpc-interface of one application.
I also want to use concept of entity which means that is part of service (one service contains multiple entities). Each entity type has own unique identifier that gives possibility to address different entities in service.
I would like to use proto like this
message UserReq {
string username = 1;
string password = 2;
}
message RegReq {
uint8 result_code = 1;
}
message RemoteEntityInterface
{
MyEntity entity = 1;
}
message GiveItemResult
{
uint8 result_code = 1;
}
service MyService {
rpc RegisterUser (UserReq) returns (RegReq) {}
rpc Login(UserReq) returns (RemoteEntityInterface) {}
}
entity MyEntity
{
rpc GiveItem (GiveItemReq) returns (GiveItemResult) {}
}
As you can see in example, I used unknown for protobuf keyword entity, this keyword means that MyService can return the interface to some remote object (MyEntity) by using Login remote method.
What are the ways to do this? (maybe write plugin or known way to modify source code of protobuf). Or maybe there are more flexible solutions than protobuf?
I also would like to use multiple parameters per one rpc; adding java-like attributes to rpc; service and entity; and data-model for entity (variables/fields) to add real-time replication support from entity to another service.
I think it is very flexible for services in game-development.
The only official way to extend .proto syntax is to define custom options.
For example, you could have something like:
extend google.protobuf.ServiceOptions {
optional bool is_entity = 123456;
}
service MyEntity
{
option (is_entity) = true;
rpc GiveItem (GiveItemReq) returns (GiveItemResult) {}
}
The default code generator will not do anything special with this option, but you can access it from your own code and from a protoc plugin if you write one.

Can gRPC method return a message with a field that could be string or null?

I'm designing a gRPC service written in Go.
In front of the gRPC service is Envoy which converts incoming HTTP requests to gRPC and converts the gRPC responses to JSON.
The requirement of this application is to have an endpoint that returns the following JSON object:
{
my_id: "AAA"
}
I can model this response pretty simply in Go like this:
// A MyResponse object.
message MyResponse {
// contents is a list of contents.
string my_id = 1;
}
But the requirement that I have is that sometimes my_id might be null. In that case, I want to get the following JSON back:
{
my_id: null
}
it
Is it possible to modify MyResponse such that my_id can be a string or a null in the JSON object that is returned? If so, how? If not, isn't this a pretty big gap in the design of gRPC?
I suggest you to use the StringValue field of the Package google.protobuf:
StringValue Wrapper message for string.
The JSON representation for StringValue is JSON string.
So in your proto files, you should import:
import "google/protobuf/wrappers.proto";
then use as example:
google.protobuf.StringValue name = 2;
For handle the values you can check the wrappers.StringValue
type of the github.com/golang/protobuf/ptypes/wrappers package and the helpers of the google.golang.org/protobuf/types/known/wrapperspb repo.

How to get Method extensions from gRPC

I am using interceptors to perform additional validation based on the optional extensions set on an RPC on incoming and out going RPCs.
Given the following gRPC schema:
extend google.protobuf.MethodOptions {
string my_option = 50006;
}
service MyService {
rpc Foo (FooRequest) returns (FooResponse) {
option (my_option) = "foo"
}
}
How do I go about getting the value of my_option? At first I had thought to get it from the request using this. However, as this is a MethodOptions it doesn't seem that its part of the descriptor. Thoughts?
Found the following answer for those who get here in the future.

Can I define a grpc call with a null request or response?

Does the rpc syntax in proto3 allow null requests or responses?
e.g. I want the equivalent of the following:
rpc Logout;
rpc Status returns (Status);
rpc Log (LogData);
Or should I just create a null type?
message Null {};
rpc Logout (Null) returns (Null);
rpc Status (Null) returns (Status);
rpc Log (LogData) returns (Null);
Kenton's comment below is sound advice:
... we as developers are really bad at guessing what we might want in the future. So I recommend being safe by always defining custom params and results types for every method, even if they are empty.
Answering my own question:
Looking through the default proto files, I came across Empty that is exactly like the Null type I suggested above :)
excerpt from that file:
// A generic empty message that you can re-use to avoid defining duplicated
// empty messages in your APIs. A typical example is to use it as the request
// or the response type of an API method. For instance:
//
// service Foo {
// rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
// }
//
message Empty {
}
You also can use predefined:
import "google/protobuf/empty.proto";
package MyPackage;
service MyService {
rpc Check(google.protobuf.Empty) returns (google.protobuf.Empty) {}
}
you can also use another bool property inside the Reply structure. like this
message Reply {
string result = 1;
bool found = 2;
}
so if you dont find the result or some error happened you can return from the service class this
return new Reply()
{
Found = false
};

Can protobuf service method return primitive type?

I'm trying to use Google protobuf and i 'm having the next descriptions:
message.proto file:
message Request {
required int32 id = 1;
optional string value = 2;
}
service.proto file:
import "message.proto";
service Service {
rpc request (Request) returns (bool);
}
I'm trying to generate c++ sources and getting an error:
$ protoc service.proto --cpp_out=/tmp/proto/build
service.proto:4:40: Expected message type.
Do i have to return user-defined types only? Are primitive (like bool or string) supported? Can i use primitive types as service method argument (instead of Request in my example)?
No, you cannot use a primitive type as either the request or response. You must use a message type.
This is important because a message type can be extended later, in case you decide you want to add a new parameter or return some additional data.
If you want to return a primitive type, wrap it in a message and return it:
message Name {
string name = 1;
}
In case you don't want to return anything, void I mean, you can just create an empty message:
message Void {}
message Name {
string name = 1;
}
..
service MyService{
rpc MyFunc(Name) returns (Void);
}
You can return scalar datatypes like bool, int, etc by making use of wrappers.proto
service.proto file:
import "message.proto";
import "google/protobuf/wrappers.proto";
service Service {
rpc request (Request) returns (.google.protobuf.BoolValue);
}

Resources