Skip to content

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 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 protocolPackage to add alongside NSmithy.Server.AspNetCore
restJson1 or simpleRestJsonNSmithy.Protocols.RestJson
rpcv2CborNSmithy.Protocols.RpcV2Cbor
grpcNSmithy.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.

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.

Program.cs
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.

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.

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.