QUANHEX.
Backend

Building Lean APIs With .NET 8 Minimal APIs

How .NET 8's minimal API pattern compares to traditional MVC controllers — and when to choose each approach for your backend architecture.

· 6 min read

.NET has long had a reputation for ceremony. Controllers, action filters, model binding conventions, route attribute syntax — there’s a lot of infrastructure between you and a working endpoint. .NET 8 Minimal APIs change that calculus significantly.

What Minimal APIs Actually Are

Minimal APIs let you define HTTP endpoints directly in Program.cs (or organized across files) without the MVC controller abstraction.

var app = WebApplication.Create(args);

app.MapGet("/health", () => Results.Ok(new { status = "healthy" }));

app.MapPost("/contact", async (ContactRequest req, IEmailService email) => {
    await email.SendAsync(req);
    return Results.Ok(new { success = true });
});

app.Run();

No controller class, no [ApiController] attribute, no [HttpPost] decorator. The route and the handler are a single declaration.

Dependency Injection Still Works

Minimal API handlers participate fully in .NET’s DI system. You can inject services directly into the handler delegate:

app.MapPost("/reservations", async (
    CreateReservationCommand cmd,
    IReservationService reservations,
    ICurrentUser currentUser
) => {
    var result = await reservations.CreateAsync(cmd, currentUser.Id);
    return result.IsSuccess
        ? Results.Created($"/reservations/{result.Value.Id}", result.Value)
        : Results.BadRequest(result.Errors);
});

The DI container resolves IReservationService and ICurrentUser automatically. The handler is a pure function from inputs to IResult.

FastEndpoints: The Structured Middle Ground

For teams who want the performance benefits of minimal APIs but the organization of controllers, FastEndpoints is worth evaluating. Each endpoint is a class with a defined request/response contract:

public class CreateReservationEndpoint : Endpoint<CreateReservationRequest, ReservationResponse>
{
    public override void Configure()
    {
        Post("/reservations");
        Roles("staff", "admin");
    }

    public override async Task HandleAsync(
        CreateReservationRequest req,
        CancellationToken ct)
    {
        var reservation = await reservationService.CreateAsync(req, ct);
        await SendAsync(reservation.ToResponse());
    }
}

FastEndpoints benchmarks faster than MVC controllers and provides a more structured home for validation, mapping, and authorization than raw minimal APIs.

When to Stick With MVC Controllers

Minimal APIs are excellent for new projects and APIs that are relatively simple in their routing and middleware needs. MVC controllers remain the right choice when:

  • Your team has deep MVC expertise and the migration cost isn’t justified
  • You’re using complex action filters that don’t map cleanly to minimal API middleware
  • You need the convention-based routing for a very large API surface

For new projects, we start with minimal APIs and reach for FastEndpoints if the project grows to need more structure. We haven’t needed full MVC controllers for a new project in two years.