grpc-dotnet
grpc-dotnet copied to clipboard
GRPC JSON transcoding : query parameters not "discovered"
This is about #167 and https://docs.microsoft.com/en-us/aspnet/core/grpc/httpapi?view=aspnetcore-5.0
Given the following proto
syntax = "proto3";
option csharp_namespace = "user_management";
import "google/api/annotations.proto";
service UserListService {
//List users
rpc ListUsers (ListUserRequest) returns (UserList) {
option (google.api.http) = {
get: "/v1/users";
};
}
}
message ListUserRequest {
int32 page_size = 1;
int32 page_nb = 2;
string order_by = 3;
string name = 4;
}
message UserList {
int32 total = 1;
int32 page_nb = 2;
repeated UserItem data = 3;
}
//Partial details for a user
message UserItem{
string id = 1;
string name = 2;
}
I would expect that ListUserRequest is exposed as query parameters
Indeed, calling http://localhost:5000/v1/users?page_size=10&page_nb=1 will correctly submit the parameters to the C# class
However, the generated swagger as explained at https://docs.microsoft.com/en-us/aspnet/core/grpc/httpapi?view=aspnetcore-5.0#enable-swaggeropenapi-support does not contain them
Every gRPC message property can be set via a parameter. If they are automatically included then there will be a lot of parameters for large messages. That's probably not what people want.
I'm not sure what the best thing is to do here. Need to research what other gRPC JSON transcoding frameworks do and think about it.
@JamesNK thanks for your answer
if there is no way to include them automatically, what is the way to include them explicitly ?
for ex, for post I can do :
option (google.api.http) = {
post: "/v1/example/echo"
body: "*"
};
however, there is no such thing for get (at least that I can see)
it seems wrong to do
option (google.api.http) = {
get: "/v1/example/echo?message={message}"
};
another point (already said in the ticket, sorry for redundancy) is that if I call http://localhost:5000/v1/users?page_size=10&page_nb=1, then it will correctly submit the parameters to the C# class -> why are they not documented in the OpenApi part if I can use them (and because it is a GET, it is the ONLY possible way to use them anyway)
final point, the google docs https://cloud.google.com/endpoints/docs/grpc-service-config/reference/rpc/google.api#google.api.HttpRule
Any fields in the request message which are not bound by the path template automatically become HTTP query parameters if there is no HTTP request body.
Hope it helps to make a decision in my favor :) :) :)
Having this work would be immensely useful. I'm currently running into the same issue, so I've been using BloomRPC client, but swagger is much more friendly.
Just to mention that I do not use this plugin anymore
The first workaounf was to declare 2 apps inside my program.cs : an OpenApi app and a grpc app
Inside the grpc app, i use the code-first approach
Inside the openapi app, I use builder.AddControllers and AddSwaggerGen
Both the grpc and the openapi controlers are calling the same business logic under the hood
That was working great if you need to provide the same services internally (grpc) and externally (openapi)
In the end, i now switched to a Backend for frontend approach so each frontend have its own api layer and calls one (or more) grpc service under the hood and I use grpccurl to to talk with grpc services in a more friendly way (not as friendly as swagger, but grpcui does not work for me, I'm going to try bloomrpc asap)
This is done in the OpenAPI integration for gRPC JSON transcoding:
https://learn.microsoft.com/en-us/aspnet/core/grpc/json-transcoding-openapi?view=aspnetcore-7.0