12

My goal is to try to put both to work as part of the incremental migration from a REST API to gRPC. We are going to start using gRPC as the way of communication between our services in our microservice architecture.

The problem is that whenever I put the gRPC service in my middleware and/or I try to force http2 protocol for the gRPC to work my REST API stops to work. Even though my Swagger documentation stops to work with both implementations the endpoints via POSTMAN are still reachable when I add the middleware, but not when I add the http2 protocol. For reference we are already using .NET Core 3.

So my question is, is it possible to have both REST and gRPC working at the same time on the same application? If so, how?

Nez
  • 121
  • 1
  • 4
  • Didn't yet had the chance to try out the new gRPC stuff with ASP.NET Core, but aren't REST and RPC fundamentally different? I mean, on RPC you get a single endpoint which takes all the requests. On REST its multiple endpoints you define via url (called resources). Sure you may put an REST gateway in front of it which then calls the gRPC and returns the result as json/xml/youcallit – Tseng Nov 04 '19 at 11:00
  • @Tseng Yes, they are different. On gRPC you have one endpoint that is the server address and from there you call the different methods and services while, yes, on REST you have different endpoints for each method and service. However it is not the route part that is having conflicts since on a gRPC only app you have a default endpoint. My endpoint is defined as follow: `app.UseEndpoints(endpoints => { // Map gRPC Services endpoints.MapGrpcService(); // Maps Controller endpoint endpoints.MapControllerRoute("default", "address");` – Nez Nov 04 '19 at 11:17
  • Update the question with the related configuration code as well as your appsettings entries for the endpoints. Its not obvious on which endpoint your gRPC is listening to. If you listen to the application root (i.e. https://example.com/) then its obvious why the other routing doesnt work. The gRPC endpoint needs to be a different one from your WebAPI endpoints, i.e. `https://example.com/grpc` (assuming you won't ever have a mvc controller named `GrpcController` " ^^ – Tseng Nov 04 '19 at 12:20
  • @Tseng I already fixed the HTTP problem, I just had to add "Http1AndHttp2" to the EndpointDefaults of the Kestrel Protocol for both POSTMAN and swagger documentation work. However, while POSTMAN still works, my documentation isn't working when I put the addGrpc on the middleware. – Nez Nov 06 '19 at 14:51
  • 4
    @Nez Were you ever able to get this working? – WBuck Jul 28 '20 at 01:13

3 Answers3

1

Yes, it is. All you need is just to configure the Kestrel endpoints parameters in your appsettings.json. Set Endpoints with WebApi and gRPC with your custom name as follow:

  "Kestrel": {
    "Endpoints": {
      "Grpc": {
        "Protocols": "Http2",
        "Url": "https://localhost:5104"
      },
      "webApi": {
        "Protocols": "Http1",
        "Url": "https://localhost:5105"
      }
    }
  }

Now you can do both access to WebApi endpoints and call the gRPC service from a client.

Majid Shahabfar
  • 4,010
  • 2
  • 28
  • 36
0

An alternative (esp. if is a transition period) is to expose just gRPC endpoints and use transcode from HTTP to gRPC in the gateway e.g. https://apisix.apache.org/docs/apisix/plugins/grpc-transcode/

Arnon Rotem-Gal-Oz
  • 25,469
  • 3
  • 45
  • 68
0

I think you can enable support for both HTTP1.1/2.0 for a single endpoint with Http1AndHttp2 option

My config in appsettings.json

{
"Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http1AndHttp2"
    }
  }
}

Then your applicationUrl inside launchSettings.json will now support both HTTP 1.1 and HTTP 2.0

P/s: I'm using .NET Core 6.0