ASP.NET Core Minimal API, .NET 6 ile birlikte gelen ve geleneksel Controller tabanli yaklasima kiyasla daha az cerceve kodu ile HTTP uc noktalari tanimlamayi saglayan bir modeldir. Bu model özellikle mikro servisler, BFF katmanları ve ic arac API'leri gibi dar kapsamlı servislerde hızlı geliştirme imkani sunar. Ancak az kod yazmak, mimari disiplini ihmal etmek anlamina gelmez. Temiz uc nokta tasarımı; rotalarin okunabilirligi, bagimliliklarin acikligi, hata sozlesmesinin tutarlılığı ve test edilebilirlik uzerine kurulmalidir.
Minimal API'nin çalışma modeli
Minimal API, WebApplication uzerinde dogrudan MapGet, MapPost, MapPut ve MapDelete gibi extension metotlari ile endpoint tanimlar. Her endpoint bir RequestDelegate veya strongly typed handler olarak çalışır. ASP.NET Core, parametre baglama, model dogrulama ve OpenAPI uretimi icin kaynak ureticilerinden yararlanir. Bu sayede JSON body'den DTO okuma, route parametrelerini cozme ve servis enjeksiyonu otomatik gerçekleşir.
Controller modelinden temel fark, HTTP işleme mantiginin sınıf hiyerarsisi yerine fonksiyon veya statik metot seviyesinde ifade edilmesidir. Bu basitlik avantaj saglarken, buyuyen projelerde endpoint'lerin daginiklasmasi riskini de beraberinde getirir. Bu nedenle endpoint gruplama, extension metotlari ve moduler kayıt desenleri erken asamada planlanmalidir.
Endpoint gruplama ve rota tasarımı
Temiz bir Minimal API projesinde rotalar tek bir Program.cs dosyasinda birikmez. Her bounded context veya modül icin ayri bir static sınıf oluşturmak yaygın bir kalıptir:
public static class ProductEndpoints
{
public static RouteGroupBuilder MapProductEndpoints(this IEndpointRouteBuilder app)
{
var group = app.MapGroup("/api/products")
.WithTags("Products")
.RequireAuthorization();
group.MapGet("/", ListProducts);
group.MapGet("/{id:int}", GetProduct);
group.MapPost("/", CreateProduct);
return group;
}
}
MapGroup kullanımı ortak on ek, etiketleme ve yetkilendirme kurallarini tek noktada toplar. Route group'lar OpenAPI dokumantasyonunda da anlamli gruplar oluşturur. URI tasarımında kaynak odaklı isimlendirme tercih edilmeli; fiil iceren path segmentlerinden kacinilmalidir.
Strongly typed handler'lar
.NET 7 ve sonrasinda handler'lari ayri siniflara tasimak mumkundur. Bu yaklaşım test edilebilirligi artirir:
public sealed class GetProductHandler
{
private readonly IProductRepository _repo;
public GetProductHandler(IProductRepository repo) => _repo = repo;
public async Task<Results<Ok<ProductDto>, NotFound>> Handle(int id, CancellationToken ct)
{
var product = await _repo.GetByIdAsync(id, ct);
return product is null ? TypedResults.NotFound() : TypedResults.Ok(product.ToDto());
}
}
Handler sinifi DI container'a kaydedilir ve endpoint'te metot grubu olarak referans verilir. Boylece is mantigi HTTP tanimindan ayrilir; birim testlerde handler dogrudan cagrilabilir.
TypedResults ve HTTP sozlesmesi
Minimal API'de Results<T1, T2, ...> ve TypedResults kullanımı, donus tiplerini açıkça ifade eder. Bu sayede OpenAPI semasi otomatik uretilir ve derleme zamani tip güvenliği sağlanır. Örneğin bir kaynak bulunamadiginda 404, dogrulama hatasinda 400, başarılı olusturmada 201 Created donmek icin union return type tercih edilir.
Hata yanitlarinda tutarlılık icin merkezi bir exception handler middleware'i veya IExceptionHandler implementasyonu kullanılmalıdır. Problem Details (RFC 7807) formati, istemcilerin hatayi makine okunabilir şekilde islemesini kolaylastirir. Her endpoint'in farklı hata JSON'i uretmesi, API tüketim maliyetini artirir.
Validasyon ve filtreleme
Minimal API'de model dogrulama icin birkac yol vardir:
- DataAnnotations: DTO uzerinde attribute tanimlayarak otomatik 400 yaniti alinabilir.
- FluentValidation:
IValidatableObjectveya endpoint filter ile entegre edilir. - Endpoint filters: .NET 7+ ile gelen bu mekanizma, cross-cutting concern'leri endpoint seviyesinde uygular.
Endpoint filter ornegi:
public sealed class ValidationFilter<TRequest> : IEndpointFilter
{
private readonly IValidator<TRequest> _validator;
public ValidationFilter(IValidator<TRequest> validator) => _validator = validator;
public async ValueTask<object?> InvokeAsync(
EndpointFilterInvocationContext ctx, EndpointFilterDelegate next)
{
var model = ctx.Arguments.OfType<TRequest>().FirstOrDefault();
if (model is null) return await next(ctx);
var result = await _validator.ValidateAsync(model, ctx.HttpContext.RequestAborted);
if (!result.IsValid)
return Results.ValidationProblem(result.ToDictionary());
return await next(ctx);
}
}
Filter'lar loglama, metrik toplama, rate limiting ve yetkilendirme icin de kullanılabilir. Ancak filter zinciri uzadikca istek basina maliyet artar; kritik olmayan işlemler icin middleware tercih edilebilir.
Performans ve allocation
Minimal API, Controller modeline gore daha düşük allocation profili sunar cunku action filter pipeline'i ve model binding katmanlarinin bir kismi devre disi kalabilir. Yine de performans icin su noktalara dikkat edilmelidir:
- AsNoTracking okuma: Salt okuma endpoint'lerinde EF Core tracking kapatilmalidir.
- Response caching: Degismeyen kaynaklar icin output cache veya HTTP cache header'lari kullanılmalıdır.
- JsonSerializerOptions: Source generator ile AOT uyumlu serialization dusunulmelidir.
- Connection pooling: Her istekte yeni bağlantı acmak yerine pool kullanılmalıdır.
BenchmarkDotNet ile endpoint basina latency ölçümü yapmak, varsayimlari veriye dayandirmak icin en güvenilir yoldur.
Güvenlik entegrasyonu
Minimal API'de yetkilendirme RequireAuthorization, policy bazli kurallar ve endpoint metadata ile yapilandirilir. Anonymous endpoint'ler bilincli olarak isaretlenmeli; varsayilan politika authenticated olmalidir. JWT bearer, API key veya cookie authentication ayni DI altyapisi uzerinden çalışır.
CSRF korumasi cookie tabanli oturumlarda önemlidir; pure API senaryolarinda bearer token yeterlidir. Input sanitization ve rate limiting, public endpoint'lerde zorunlu savunma katmanlaridir.
Test stratejisi
WebApplicationFactory<Program> ile entegrasyon testleri yazilir. Handler siniflari ayri test edilir; HTTP katmanı ise factory uzerinden gerçek pipeline ile calistirilir. Testlerde in-memory veritabanı veya Testcontainers tercih edilebilir.
Örnek entegrasyon testi yaklasimi:
- Factory'de test servisleri ile gerçek bağımlılıkları değiştir.
- Her senaryo icin izole veritabanı veya transaction rollback kullan.
- OpenAPI semasini contract testi olarak değerlendir.
Moduler monolit icin kayıt deseni
Büyük cozumlerde her modül kendi endpoint extension'ini sağlar ve Program.cs sadece modulleri birlestirir:
builder.Services.AddCatalogModule();
builder.Services.AddOrderModule();
var app = builder.Build();
app.MapCatalogEndpoints();
app.MapOrderEndpoints();
Bu desen, modül sınırları netlestirir ve takimlarin paralel calismasina imkân tanir. Modül basina ayri assembly kullanmak derleme surelerini de iyilestirebilir.
Yaygın hatalar
Minimal API projelerinde sik karsilasilan sorunlar sunlardir: tüm endpoint'lerin tek dosyada birikmesi, is mantiginin inline lambda icinde kalmasi, hata sozlesmesinin standart olmamasi, OpenAPI etiketlerinin eksikligi ve cancellation token'in ihmal edilmesi. Her istek CancellationToken almali; uzun suren işlemler iptal sinyaline duyarli olmalidir.
Bir baska tuzak, Minimal API'yi "script gibi" kullanip domain katmanini atlamaktir. HTTP ince bir adaptasyon katmanı olmali; is kurallari repository ve domain servislerinde kalmalidir. Bu ayrim, Controller'dan Minimal API'ye geciste de gecerlidir.
Özet mimari ilkeler
Temiz Minimal API tasarımı su ilkelerle ozetlenebilir: endpoint'leri modül bazinda grupla, handler'lari ayri siniflara taşı, TypedResults ile HTTP sozlesmesini açık tut, filter ve middleware ile cross-cutting concern'leri merkezilestir, DI ile test edilebilirligi koru, performans olcumunu erken yap ve güvenlik politikasini varsayilan olarak sik tut. Bu yaklaşım, az kod yazmanin getirdigi hizi mimari kalite ile dengeleyerek sürdürülebilir bir API yuzeyi oluşturur.
Versioning ve geriye uyumluluk
Minimal API'de API versiyonlama icin URL segment, header veya query parametresi kullanılabilir. Asp.Versioning.Http paketi route group'larla entegre çalışır. Breaking change'ler yeni major versiyonda sunulmali; eski versiyon belirli bir deprecation penceresi sonra kaldirilmalidir. Versioning metadata'si OpenAPI ciktisina yansitilarak istemci geliştiriciler bilgilendirilir.
Response contract degisikliklerinde additive change tercih edilmeli: yeni alan eklemek breaking degildir, alan kaldirmak veya tip değiştirmek breaking'dir. Source generator ile client SDK uretiliyorsa semver disiplini daha da onem kazanir.
Observability entegrasyonu
Her endpoint icin structured log, trace span ve metrik üretmek uretimde sorun cozmeyi hizlandirir. OpenTelemetry ASP.NET Core instrumentation otomatik HTTP span oluşturur; custom activity source ile handler seviyesinde alt span eklenebilir. Metrik olarak request count, error rate, p95 latency ve aktif connection sayisi izlenmelidir.
Correlation ID middleware ile istemciden gelen veya uretilen ID tüm log satirlarina eklenir. Distributed trace'te kuyruk ve veritabanı cagrilari parent span'e baglanir.