Reputation: 393
I am writing a new service in golang using protobuf. I want to model the following Request JSON in the .proto file.
[
{
"var": ["myVariable1","myVariable2"],
"key1": 123123,
"key2": 1122,
"key3": "abcd-0101"
},
{
"var": ["myVariable1"],
"key1": 123124,
"key2": 1123,
"key3": "abcd-0102"
},
]
There are two problems currently :
Following is my .proto file :
syntax = "proto3";
package pb;
import "google/protobuf/empty.proto";
import "google/api/annotations.proto";
service Transmitter {
rpc GetVariables(GetVariablesRequest) returns (GetVariablesResponse) {
option (google.api.http) = {
post: "/api/v1/{Service}/getVars"
body: "*"
};
};
}
message GetVariablesRequest {
string Service = 1;
repeated GetVarInput in = 2;
}
message GetVariablesResponse {
string msg = 1;
}
message GetVarInput {
map<string,string> Input = 2;
}
I have tried with bytes instead of repeated GetVarInput, but it always comes empty. Also tried body: "*" and body : "in"
Please provide some pointers.
Upvotes: 6
Views: 16221
Reputation: 4936
service UserService {
rpc GetUsers(GetUsersRequest) returns (Users) {
option (google.api.http) = {
get : "/users"
};
};
rpc GetUser(GetUserRequest) returns (User) {
option (google.api.http) = {
get : "/users/{user_id}"
};
};
}
message User {
string id = 1;
string display_name = 2;
string icon_image_path = 3;
string background_image_path = 4;
string profile = 5;
string email = 6;
google.protobuf.Timestamp created_at = 8;
google.protobuf.Timestamp updated_at = 9;
google.protobuf.Timestamp deleted_at = 10;
}
message Users {
repeated User user = 1;
}
message GetUsersRequest {}
message GetUserRequest { string user_id = 1; }
Upvotes: 1
Reputation: 37
Another approach is usage of Any
message in your .proto file. In this case you could have a repeated map with any GO types you need. But this approach is a bit overhead as it gives you a flexibility using strongly typed programming language. Here's an example:
message Any {
string type = 1;
bytes value = 2;
}
and in your GO code:
func GetRPCAnyValue(value interface{}) *pb.Any {
bValue, type_val, _ := MarshlizeValue(value)
return &pb.Any{
Type: type_val,
Value: bValue,
}
}
Upvotes: 0
Reputation: 12156
The answer by Satyam Zode seems like the most reasonable one.
In your original question, you are trying to keep all the flexibility and dynamic nature of JSON, and in that case trying to convert it into protobuf makes little sense. You could just have a string field that contains the json.
However, protobuf does handle future changes to RequestMessage
contents quite well, so you do not have to know the final set of fields yet. Just follow Updating a Message Type to keep them compatible between different .proto file versions.
Upvotes: -1
Reputation: 185
You can write a message for your json like this:
message RequestMessage {
string var = 0;
double key1 = 1;
double key2 = 2;
string key3 = 3;
}
Further, you can create another message which contains an array of RequestMessage
message Request {
repeated RequestMessage request = 0;
}
Upvotes: 3