grpc-dotnet icon indicating copy to clipboard operation
grpc-dotnet copied to clipboard

GRPC JSON transcoding : query parameters not "discovered"

Open christopheblin opened this issue 2 years ago • 4 comments

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

Capture d’écran 2021-10-13 224905

christopheblin avatar Oct 13 '21 20:10 christopheblin

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 avatar Oct 14 '21 21:10 JamesNK

@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 :) :) :)

christopheblin avatar Oct 15 '21 13:10 christopheblin

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.

TXP-AlbertPucciani avatar Apr 18 '22 20:04 TXP-AlbertPucciani

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)

christopheblin avatar May 16 '22 13:05 christopheblin

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

JamesNK avatar Dec 27 '22 01:12 JamesNK