Skip to content

.NET Server Setup

Host IonPath services in an ASP.NET Core application with dependency injection, RPC endpoint mapping, and interceptors.

Basic Setup

Register IonPath services and map RPC endpoints in your Program.cs:

var builder = WebApplication.CreateBuilder(args);

// Register IonPath protocol services
builder.Services.AddIonProtocol(options =>
{
    options.WithTransport<MyAppTransport>();
});

// Register your service implementations
builder.Services.AddScoped<IUserService, UserServiceImpl>();

var app = builder.Build();

// Map all IonPath RPC endpoints
app.MapRpcEndpoints();

app.Run();

Implementing a Service

Implement the generated interface (IServiceName) and register it with DI:

public class UserServiceImpl : IUserService
{
    private readonly IDbContext _db;

    public UserServiceImpl(IDbContext db) => _db = db;

    public async Task<User> GetUser(
        uint spaceId,  // base arg
        uint userId,   // method arg
        CancellationToken ct)
    {
        return await _db.Users
            .Where(u => u.SpaceId == spaceId && u.Id == userId)
            .FirstAsync(ct);
    }
}

Base arguments and method arguments are flattened into the method signature. A CancellationToken is automatically passed for request cancellation.

Streaming Methods

Server-streaming methods return IAsyncEnumerable<T>:

public async IAsyncEnumerable<User> WatchUpdates(
    uint spaceId,
    [EnumeratorCancellation] CancellationToken ct)
{
    await foreach (var update in _updates.ReadAllAsync(ct))
    {
        if (update.SpaceId == spaceId)
            yield return update;
    }
}

Interceptors

Interceptors provide cross-cutting concerns (logging, metrics, auth) around method execution:

builder.Services.AddIonProtocol(options =>
{
    options.AddInterceptor<LoggingInterceptor>();
    options.AddInterceptor<MetricsInterceptor>();
});

Interceptors execute in registration order. They receive the execution context and can inspect/modify the request, response, or error.

Ticket-Based Authentication

IonPath uses ticket-based authentication instead of standard HTTP headers. Configure the ticket exchange:

builder.Services.AddIonProtocol(options =>
{
    options.WithTicketExchange<JwtTicketExchange>();
});

The IIonTicketExchange interface validates tickets and returns the associated identity. For WebSocket, the ticket is passed via the subprotocol header; for HTTP, via a custom header.

OpenTelemetry

IonPath instruments method calls with OpenTelemetry spans and metrics via the Instruments class:

// Automatically creates spans for each RPC method call:
// ion.rpc.{service}.{method}
// With attributes: ion.service, ion.method, ion.status