Î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.
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");
});