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.
What can share a port
Section titled “What can share a port”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 (
@httppaths), rpcv2Cbor (/service/…/operation/…), and the awsJson family (POST /withX-Amz-Target) occupy different route shapes, so any mix of these coexists on one listener. - Same-route protocols need separate listeners.
awsJson1_0andawsJson1_1both bindPOST /and differ only byContent-Type. Generated routing does not dispatch onContent-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.
Pinning a protocol to a port
Section titled “Pinning a protocol to a 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.