Learn .NET  

Understanding FastEndpoints in .NET

In the evolution of ASP.NET Core, we have moved from the rigid structure of MVC (Model-View-Controller) to the streamlined simplicity of Minimal APIs. However, as applications grow, Minimal APIs can become disorganized, and Controllers often suffer from “bloat”—violating the Single Responsibility Principle. 

Enter FastEndpoints.

This library is not just another framework; it is a philosophy shift. It wraps the performance of Minimal APIs in a structured, maintainable pattern known as REPR (Request-Endpoint-Response). In this post, we will dive deep into what FastEndpoints is, why it matters, and how to implement it in your .NET projects. 

The Problem with Controllers 

Traditionally, .NET developers group logic by resource. A UserController, for example, might handle Get, Create, Update, and Delete operations.

While this looks organized initially, it leads to several issues:

  • Constructor Bloat: A controller injecting dependencies for all its methods means every request instantiates services it might not need.

  • Hidden Coupling: Shared private methods inside a controller create tight coupling between unrelated endpoints (e.g., “Get User” logic bleeding into “Update User”).

  • Violation of SRP: A controller handles many responsibilities, rather than just one.

The Solution: The REPR Pattern 

FastEndpoints implements the REPR pattern, which stands for Request-Endpoint-Response.

Instead of grouping by resource (a Controller), you group by feature (an Endpoint). Each endpoint is a distinct class dedicated to a single purpose (e.g., CreateUserEndpoint, GetUserEndpoint).

The Components

  1. Request: A DTO (Data Transfer Object) defining what the client sends.

  2. Endpoint: A class containing the logic for only that specific request.

  3. Response: A DTO defining what the server returns.

Getting Started with FastEndpoints 

Let’s look at how to implement a simple “Create User” feature using FastEndpoints in .NET 8.

  1. Installation

First, install the necessary package via the NuGet Package Manager or CLI:

dotnet add package FastEndpoints
  1. Configuration

In your Program.cs, register and enable FastEndpoints. It sits on top of the existing ASP.NET Core pipeline, so it integrates seamlessly.

using FastEndpoints;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddFastEndpoints(); // Register services
var app = builder.Build();
app.UseFastEndpoints(); // Register middleware
app.Run();
  1. Defining the Endpoint

Here is where the magic happens. Instead of a method inside a controller, we define a class.

The DTOs:

public class CreateUserRequest
{
    public string FirstName { get; set; } = default!;
    public string LastName { get; set; } = default!;
    public string Email { get; set; } = default!;
}
public class CreateUserResponse
{
    public string FullName { get; set; } = default!;
    public string Message { get; set; } = default!;
}

 The Endpoint:

using FastEndpoints;
public class CreateUserEndpoint : Endpoint<CreateUserRequest, CreateUserResponse>
{
    public override void Configure()
    {
        Post("/api/users/create");
        AllowAnonymous();
    }
    public override async Task HandleAsync(CreateUserRequest req, CancellationToken ct)
    {
        // Simulate database logic
        var fullName = $"{req.FirstName} {req.LastName}";
        // Send the response
        await SendAsync(new CreateUserResponse
        {
            FullName = fullName,
            Message = "User created successfully!"
        }, cancellation: ct);
    }
} 

Breakdown of the Code

  • Inheritance: The class inherits from Endpoint<TRequest, TResponse>, providing strict typing immediately.

  • Configure(): This replaces route attributes ([HttpPost], [Route]). You define the configuration imperatively, which is often cleaner and more discoverable.

  • HandleAsync(): This contains your business logic. It takes the strongly-typed Request object and a CancellationToken automatically.

Key Features & Benefits

1. Built-in Validation

FastEndpoints integrates heavily with FluentValidation. You don’t need to manually check ModelState.IsValid. You simply define a validator, and the library handles the 400 Bad Request response automatically if validation fails.

public class CreateUserValidator : Validator<CreateUserRequest>
{
    public CreateUserValidator()
    {
        RuleFor(x => x.Email).NotEmpty().EmailAddress();
        RuleFor(x => x.FirstName).NotEmpty().MinimumLength(3);
    }
} 

2. Vertical Slice Architecture

By forcing you to create a file per endpoint, FastEndpoints naturally pushes your project toward Vertical Slice Architecture. All files related to a feature (the Endpoint, the Request/Response DTOs, the Validator, and the Mapper) can live in a single folder. This makes navigating code significantly easier than jumping between Controllers/, Models/, and Services/ folders.

3. Performance

Because FastEndpoints is a wrapper around ASP.NET Core’s Minimal APIs, it is extremely performant—significantly faster than traditional MVC Controllers and effectively on par with raw Minimal APIs. It builds the expression trees for mapping and validation at startup, ensuring runtime speed is maximized.

Conclusion

FastEndpoints offers the “sweet spot” for modern .NET API development. It provides the structure that Minimal APIs lack and removes the bloat that Controllers impose. If you are looking to build maintainable, high-performance, and type-safe APIs, adopting the REPR pattern with FastEndpoints is a powerful choice.

Happy Coding !!!