See More

A very common reason is a wrong site baseUrl configuration.\n

Current configured baseUrl = / (default value)\n

We suggest trying baseUrl = \n\n',document.body.prepend(n);var e=document.getElementById("__docusaurus-base-url-issue-banner-suggestion-container"),s=window.location.pathname,o="/"===s.substr(-1)?s:s+"/";e.textContent=o}document.addEventListener("DOMContentLoaded",function(){void 0===window.docusaurus&&insertBanner()})

Skip to main content

Getting Started

Installation

Install the three core packages:

dotnet add package ZeroAlloc.Rest
dotnet add package ZeroAlloc.Rest.Generator
dotnet add package ZeroAlloc.Rest.SystemTextJson

The generator package must be referenced as an analyzer so that the SDK does not add it as a runtime dependency:

<PackageReference Include="ZeroAlloc.Rest" Version="x.y.z" />
<PackageReference Include="ZeroAlloc.Rest.Generator"
Version="x.y.z"
OutputItemType="Analyzer"
ReferenceOutputAssembly="false" />
<PackageReference Include="ZeroAlloc.Rest.SystemTextJson" Version="x.y.z" />

Define an interface

Decorate your interface with [ZeroAllocRestClient]. The source generator picks it up and emits a concrete implementation at compile time.

using ZeroAlloc.Rest.Attributes;

[ZeroAllocRestClient]
public interface IUserApi
{
[Get("/users/{id}")]
Task<UserDto> GetUserAsync(int id, CancellationToken ct = default);

[Post("/users")]
Task<UserDto> CreateUserAsync([Body] CreateUserRequest request, CancellationToken ct = default);

[Delete("/users/{id}")]
Task DeleteUserAsync(int id, CancellationToken ct = default);
}

public record UserDto(int Id, string Name);
public record CreateUserRequest(string Name);

Register in ASP.NET Core or a generic host

The generator also emits an AddI{InterfaceName} extension method:

// Program.cs
builder.Services.AddIUserApi(options =>
{
options.BaseAddress = new Uri("https://api.example.com");
options.UseSerializer<SystemTextJsonSerializer>();
});

This registers IUserApi as a typed HttpClient via IHttpClientFactory. The underlying HttpClient is managed by the factory's handler lifetime.

Use the client

public class UserService(IUserApi api)
{
public async Task<UserDto> GetUserAsync(int id, CancellationToken ct = default)
=> await api.GetUserAsync(id, ct);
}

What the generator produces

Given the interface above, the generator writes two files at compile time:

  • IUserApi.g.csUserApiClient : IUserApi with typed HTTP calls
  • IUserApi.DI.g.csAddIUserApi(IServiceCollection, Action<ZeroAllocClientOptions>) extension

You can inspect the generated code in Visual Studio via Analyzers → ZeroAlloc.Rest.Generator → Generated files.

Next steps

  • Routing — path parameters and route templates
  • Parameters — query strings, request bodies, and headers
  • Serialization — plug in System.Text.Json, MemoryPack, or your own serializer