Arhitectura Microserviciilor REST de Mare Viteză cu ASP.NET Core Minimal APIs, Dependency Injection și Validation în C# (.NET)

Ghid complet de producție pentru dezvoltarea microserviciilor cu ASP.NET Core Minimal APIs în .NET 8: organizarea rutelor cu MapGroup, Endpoint Filters, validare cu FluentValidation, Keyed Services și compatibilitate Native AOT.

Sintaxă C#
app.MapGroup('/api').WithTags('Orders').MapPost('/', CreateOrder);

Înainte de .NET 6, scrierea unui API REST în ASP.NET Core necesita o ierarhie greoaie de controlere MVC (ControllerBase), atribute repetitive și o mulțime de fișiere de configurare (Startup.cs). Acest stil tradițional introducea un overhead substanțial de rutare bazată pe reflexie.

Minimal APIs reprezintă arhitectura modernă standard în .NET 8 și .NET 9: oferă performanță de vârf cu minim de cod, compatibilitate nativă cu compilarea Native AOT și o structură extrem de curată pentru arhitecturi modulare de microservicii.

Microserviciu Modular cu MapGroup, Filtre și Validare
using Microsoft.AspNetCore.Http.HttpResults;

var builder = WebApplication.CreateSlimBuilder(args); // Builder optimizat pentru viteză

// Înregistrarea serviciilor în containerul de Dependency Injection:
builder.Services.AddScoped<IComandaRepository, ComandaRepository>();

var app = builder.Build();

// Gruparea rutelor cu prefix comun și tag OpenAPI pentru Swagger:
var ruteComenzi = app.MapGroup("/api/v1/comenzi")
    .WithTags("Comenzi")
    .AddEndpointFilter(async (context, next) => {
        // Filtru global la nivel de grup (logging, securitate, audit):
        Console.WriteLine($"Apel primit: {context.HttpContext.Request.Path}");
        return await next(context);
    });

// Înregistrarea endpoint-urilor tipizate:
ruteComenzi.MapGet("/{id:long}", async Task<Results<Ok<ComandaDto>, NotFound>> (long id, IComandaRepository repo) =>
{
    var comanda = await repo.ObtineDupaIdAsync(id);
    return comanda is not null ? TypedResults.Ok(comanda) : TypedResults.NotFound();
});

ruteComenzi.MapPost("/", async Task<Results<Created<ComandaDto>, BadRequest<string>>> (CreareComandaRequest req, IComandaRepository repo) =>
{
    if (string.IsNullOrWhiteSpace(req.NumeClient))
        return TypedResults.BadRequest("Numele clientului este obligatoriu!");

    var comandaNoua = await repo.CreazaAsync(req);
    return TypedResults.Created($"/api/v1/comenzi/{comandaNoua.Id}", comandaNoua);
});

app.Run();

Keyed Services în .NET 8

O facilitate extrem de cerută introdusă în .NET 8 este Keyed Services, permițând înregistrarea mai multor implementări ale aceleiași interfețe distinse printr-o cheie unică:

// Înregistrare:
builder.Services.AddKeyedScoped<INotificareService, EmailService>("email");
builder.Services.AddKeyedScoped<INotificareService, SmsService>("sms");

// Injectare directă în endpoint:
app.MapPost("/notifica", ([FromKeyedServices("email")] INotificareService emailSender) => {
    emailSender.TrimiteNotificare("Mesaj important");
});