Skip to content

Hosting & Multiple Protocols

A service can declare more than one protocol trait. When it does, codegen emits a Map{Service} extension with a generated {Service}Protocols flags enum. Every selected protocol resolves the same handler you registered with Add{Service}Handler. The handler deals only in model types, so nothing about it is protocol-specific.

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddWeatherServiceHandler<WeatherHandler>(); // one handler
var app = builder.Build();
app.MapWeatherService(
WeatherServiceProtocols.RestJson1 | WeatherServiceProtocols.RpcV2Cbor);
app.Run();

A client picks the protocol by which endpoint it calls; the wire serialization lives entirely in each protocol’s binding.

Endpoints are port-agnostic — ports are a deployment concern, so the generated Map extension never binds one. Whether two protocols can share a listener depends on their routes and transport:

  • Disjoint routes share a port. restJson1 (@http paths), rpcv2Cbor (/service/…/operation/…), and the awsJson family (POST / with X-Amz-Target) occupy different route shapes, so any mix of these coexists on one listener.
  • Same-route protocols need separate listeners. awsJson1_0 and awsJson1_1 both bind POST / and differ only by Content-Type. Generated routing does not dispatch on Content-Type, so exposing both means pinning each to its own port.
  • gRPC needs its own listener. gRPC requires HTTP/2; cleartext gRPC does not share an HTTP/1.1 port reliably. Give it a dedicated HTTP/2 port.

Use ASP.NET Core’s RequireHost to scope a protocol’s endpoints to a specific port, and configure Kestrel to listen there:

builder.WebHost.ConfigureKestrel(options =>
{
options.ListenLocalhost(5000); // HTTP/1.1 — REST
options.ListenLocalhost(5001, o => o.Protocols = HttpProtocols.Http2); // gRPC
});
var app = builder.Build();
app.MapGroup("")
.MapWeatherService(WeatherServiceProtocols.RestJson1);
app.MapGroup("")
.RequireHost("*:5001")
.MapWeatherService(WeatherServiceProtocols.Grpc);
app.Run();

See gRPC for the full gRPC hosting example.