Servers
NSmithy generates handler interfaces whose methods accept modeled inputs and return modeled outputs. You implement the operations; the runtime handles serialization, dispatch, and modeled errors.
Reference the protocol package
Section titled “Reference the protocol package”Reference NSmithy.Server.AspNetCore and the package for each protocol your
server generates. The host is protocol-agnostic and does not bring in protocol
or codec packages itself; each protocol package brings its required codecs.
The nsmithy-server template adds the matching reference automatically.
| Service protocol | Package to add alongside NSmithy.Server.AspNetCore |
|---|---|
restJson1 or simpleRestJson | NSmithy.Protocols.RestJson |
rpcv2Cbor | NSmithy.Protocols.RpcV2Cbor |
grpc | NSmithy.Protocols.Grpc |
When upgrading an existing REST/JSON or gRPC server, add the corresponding protocol package explicitly, using the same NSmithy version as the host.
Implement an operation
Section titled “Implement an operation”For a Library service with a GetBook operation, modeled as in
Modeling contracts, implement the generated
service interface:
internal sealed class LibraryHandler : ILibraryServiceHandler{ public Task<GetBookOutput> GetBookAsync( GetBookInput input, CancellationToken ct = default) { if (input.Id != "1") throw new BookNotFound("Book not found.");
return Task.FromResult(new GetBookOutput(input.Id, "The Odyssey")); }}Return an output for success; throw a generated error for a modeled failure. The selected protocol determines the response encoding and status.
Register and map
Section titled “Register and map”using Example.Library;
var builder = WebApplication.CreateBuilder(args);builder.Services.AddLibraryServiceHandler<LibraryHandler>();
var app = builder.Build();app.MapLibraryService();app.Run();Add{Service}Handler<THandler> registers the implementation, service metadata,
and default server runtime. Map{Service} maps the first declared supported
server protocol. To select several, see
Hosting multiple protocols.
Separate operation handlers
Section titled “Separate operation handlers”The service interface inherits one interface per operation:
public interface IGetBookHandler{ Task<GetBookOutput> GetBookAsync(GetBookInput input, CancellationToken ct = default);}
public interface ILibraryServiceHandler : IGetBookHandler { }Endpoints resolve the per-operation interfaces. To split a service across implementations, register each one instead of using the aggregate helper:
builder.Services.AddLibraryService();builder.Services.AddScoped<IGetBookHandler, GetBookHandler>();Register a handler for every mapped operation. GetBookHandler implements
IGetBookHandler with the same method shown above.
Request validation
Section titled “Request validation”The runtime validates supported constraints before invoking the handler. See Validation for checked traits, error responses, and streaming limits.
See Protocol status for ASP.NET Core protocol support.