ZeroAlloc.Rest.Generator
1.1.2
See the version list below for details.
dotnet add package ZeroAlloc.Rest.Generator --version 1.1.2
NuGet\Install-Package ZeroAlloc.Rest.Generator -Version 1.1.2
<PackageReference Include="ZeroAlloc.Rest.Generator" Version="1.1.2"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="ZeroAlloc.Rest.Generator" Version="1.1.2" />
<PackageReference Include="ZeroAlloc.Rest.Generator"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add ZeroAlloc.Rest.Generator --version 1.1.2
#r "nuget: ZeroAlloc.Rest.Generator, 1.1.2"
#:package ZeroAlloc.Rest.Generator@1.1.2
#addin nuget:?package=ZeroAlloc.Rest.Generator&version=1.1.2
#tool nuget:?package=ZeroAlloc.Rest.Generator&version=1.1.2
ZeroAlloc.Rest
ZeroAlloc.Rest is a source-generated, Native AOT-compatible REST client for .NET 10+. Define your HTTP API as a C# interface — the Roslyn generator emits a fully type-safe, zero-reflection implementation at compile time. No runtime code generation, no IL emit, no allocations beyond the HTTP layer itself.
Install
The source generator is bundled into the main package — a single PackageReference is all you need:
dotnet add package ZeroAlloc.Rest
dotnet add package ZeroAlloc.Rest.SystemTextJson
Or via <PackageReference>:
<PackageReference Include="ZeroAlloc.Rest" Version="x.y.z" />
<PackageReference Include="ZeroAlloc.Rest.SystemTextJson" Version="x.y.z" />
The standalone
ZeroAlloc.Rest.Generatorpackage is still published for backwards compatibility with existing direct PackageReferences, but new consumers should reference onlyZeroAlloc.Rest.
Optional: resilience policies
To add retry, timeout, and circuit-breaker behaviour to a client, install the bridge package alongside ZeroAlloc.Resilience:
dotnet add package ZeroAlloc.Rest.Resilience
dotnet add package ZeroAlloc.Resilience
Quick Start
1. Define your API interface:
using ZeroAlloc.Rest.Attributes;
[ZeroAllocRestClient]
public interface IUserApi
{
[Get("/users/{id}")]
Task<UserDto> GetUserAsync(int id, CancellationToken ct = default);
[Get("/users")]
Task<List<UserDto>> ListUsersAsync([Query] string? name = null, CancellationToken ct = default);
[Post("/users")]
Task<UserDto> CreateUserAsync([Body] CreateUserRequest request, CancellationToken ct = default);
[Delete("/users/{id}")]
Task DeleteUserAsync(int id, CancellationToken ct = default);
}
2. Register in DI:
builder.Services.AddIUserApi(options =>
{
options.BaseAddress = new Uri("https://api.example.com");
options.UseSerializer<SystemTextJsonSerializer>();
});
3. Inject and use:
public class UserService(IUserApi api)
{
public Task<UserDto> GetAsync(int id) => api.GetUserAsync(id);
}
The generator produces UserApiClient — a sealed class implementing IUserApi — at compile time. No reflection, no proxies, no DynamicMethod.
Performance
Measured on .NET 10.0.4, Windows 11, X64. In-memory handler; no real network I/O. See docs/benchmarks.md for methodology and full results.
| Method | Mean | vs Refit | Allocated |
|---|---|---|---|
| Raw HttpClient (GET baseline) | 1,648 ns | — | 1.38 KB |
| ZeroAlloc.Rest GET | 1,933 ns | 3.2× faster | 1.74 KB |
| Refit GET | 6,123 ns | 1× | 3.03 KB |
| ZeroAlloc.Rest QueryParam | 2,474 ns | 5.5× faster | 1.85 KB |
| Refit QueryParam | 13,509 ns | 1× | 3.67 KB |
Features
- Source-generated — zero runtime reflection; compile-time type safety
- Native AOT compatible — no
DynamicMethod, no IL emit, noType.GetType - Per-method serializer override —
[Serializer(typeof(MySerializer))]for mixed protocols - Path, query, body, and header parameters —
{id},[Query],[Body],[Header("X-Api-Key")] Result<T, HttpError>— typed success/error returns viaZeroAlloc.Results; no exception-throwing on 4xx/5xx- OpenAPI code generation —
OpenApiInterfaceGeneratorAPI + MSBuild<ZeroAllocApiSpec>task - Pluggable serializers — System.Text.Json, MemoryPack, MessagePack, or bring your own
- IHttpClientFactory integration —
AddI{Interface}generated extension method - Resilience bridge —
ZeroAlloc.Rest.Resiliencewraps any client with[Retry],[Timeout],[CircuitBreaker], and[RateLimit]viaAddRestResilience<,,>()
Telemetry
Every generated client emits OpenTelemetry-compatible signals out of the box, with no extra dependency beyond the BCL System.Diagnostics primitives.
Tracing. An ActivitySource("ZeroAlloc.Rest") produces one span per call, named Interface.Method. Tags: http.method, http.status_code, server.address, rest.method. Exceptions set ActivityStatusCode.Error with the message.
Metrics. The generator emits rest.requests_total (counter) and rest.request_duration_ms (histogram) under the ZeroAlloc.Rest Meter. Tags: http.method, http.status_code, server.address, rest.method (the generated Interface.Method identifier).
The counter is incremented only on the success path. On exception, the histogram records the elapsed duration but the counter is left untouched — this lets operators distinguish failed attempts via histogram count vs. counter delta. The exception-path histogram carries only http.method and rest.method, since http.status_code and server.address may not be known.
Subscription:
services.AddOpenTelemetry()
.WithTracing(t => t.AddSource("ZeroAlloc.Rest"))
.WithMetrics(m => m.AddMeter("ZeroAlloc.Rest"));
Documentation
| Page | Description |
|---|---|
| Getting Started | Install, register, and make your first call |
| Routing | Route templates and path parameters |
| Parameters | Query, body, header, and path parameters |
| Serialization | Built-in serializers and custom IRestSerializer |
| Dependency Injection | Generated DI extension and IHttpClientFactory |
| Native AOT | AOT safety guarantees and publish configuration |
| OpenAPI Code Generation | Generate interfaces from OpenAPI specs |
| Benchmarks | Performance comparison vs Refit and raw HttpClient |
| Testing | Testing patterns with WireMock.Net |
| Advanced | Result<T, HttpError>, multiple serializers, edge cases |
| Resilience | Retry, timeout, circuit-breaker, and rate-limit via ZeroAlloc.Rest.Resilience |
| Cookbook | End-to-end recipes |
License
MIT
Learn more about Target Frameworks and .NET Standard.
This package has no dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.