Skip to content

Quickstart

Build and run a working Immediate.Handlers endpoint in about five minutes.

2 min read

This gets one handler running end to end, reachable over HTTP. For a fuller walkthrough that adds one package per page, start the tutorial instead.

Create a new project

If you already have a .NET project you can skip this step.

terminal
dotnet new web -n MyApp
cd MyApp

Add packages

terminal
dotnet add package Immediate.Handlers
dotnet add package Immediate.Apis

See Installation for the other packages and how they depend on each other.

Create your first handler

A handler is a partial class marked [Handler] containing exactly one Handle or HandleAsync method. Everything else — the pipeline class, the DI registration, the endpoint — is generated.

📝 Note: to keep things simple this fakes the user. In a real application you would load one from a database.

GetUserQuery.cs
using Immediate.Apis.Shared;
using Immediate.Handlers.Shared;

namespace MyApp;

[Handler]
[MapGet("/api/users/{userId:int}")]
public static partial class GetUserQuery
{
	public sealed record Query
	{
		public required int UserId { get; init; }
	}

	public sealed record User(int UserId, string Username);

	private static ValueTask<User> HandleAsync(
		Query query,
		CancellationToken token
	)
	{
		var user = new User(query.UserId, "john");

		return ValueTask.FromResult(user);
	}
}

Wire it up

Two calls: one to register the handlers with DI, one to map the endpoints. MyApp here is the assembly identifier, derived from your project name.

Program.cs
using MyApp;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddMyAppHandlers();

var app = builder.Build();

app.MapMyAppEndpoints();

app.Run();

Run it

terminal
dotnet run

Then, from another terminal:

terminal
curl http://localhost:5000/api/users/42
# {"userId":42,"username":"john"}

That’s a complete, running application. The {UserId} route parameter was bound to the Query record automatically — see Binding request data for the rules.

Call the handler directly

You don’t need HTTP to use a handler. Inject the generated GetUserQuery.Handler anywhere:

Consumer.cs
public sealed class Consumer(GetUserQuery.Handler handler)
{
	public async Task ConsumeAsync(CancellationToken token)
	{
		var response = await handler.HandleAsync(
			new GetUserQuery.Query { UserId = 42 },
			token
		);

		// do something with response
	}
}