Furkan KapukayaYazılım geliştirme
C# ve .NET3 dk okuma

ASP.NET Core Middleware: İstek İşleme Hattını Anlamak

ASP.NET Core'da middleware kavramı, istek hattının çalışma sırası, yerleşik middleware'ler, özel middleware yazma, sıralama hataları ve filtrelerle farkı.

ASP.NET Core'da her HTTP isteği, uygulamanıza ulaşmadan önce bir dizi bileşenden geçer: hata yakalama, HTTPS yönlendirme, statik dosyalar, kimlik doğrulama, yetkilendirme... Bu bileşenlere middleware denir ve sıraları uygulamanın davranışını doğrudan belirler.

Hat (pipeline) mantığı

Middleware'ler bir zincir gibi çalışır. Her biri isteği alır, isterse bir şey yapar, sonra sıradakine iletir; yanıt dönerken de aynı yolu ters yönde izler.

İstek → [Hata yakalama] → [HTTPS] → [Statik dosya] → [Kimlik doğrulama] → [Yetkilendirme] → Uç nokta
Yanıt ← ............................................................................ ←

Bir middleware zinciri kısa kesebilir: statik dosya bulunursa istek uç noktaya hiç ulaşmaz.

Önerilen sıra

var app = builder.Build();

app.UseExceptionHandler();      // en başta: sonraki her şeyin hatasını yakalar
app.UseHsts();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCors();
app.UseRateLimiter();
app.UseAuthentication();        // önce kim olduğunu bul
app.UseAuthorization();         // sonra yetkisini kontrol et
app.MapControllers();

Sıralama hataları

  • UseAuthorization'ı UseAuthentication'dan önce koymak: kullanıcı her zaman anonim görünür.
  • Hata yakalayıcıyı sona koymak: önceki adımlarda oluşan hatalar yakalanmaz.
  • CORS'u uç noktalardan sonra eklemek: tarayıcı istekleri reddedilir.
  • Reverse proxy arkasında UseForwardedHeaders'ı unutmak: uygulama gerçek IP'yi ve HTTPS bilgisini göremez. Bkz. Nginx ve reverse proxy.

Özel middleware yazmak

Örneğin her isteğe bir korelasyon kimliği ekleyen ve süreyi loglayan bir middleware:

public class IstekSuresiMiddleware(RequestDelegate next, ILogger<IstekSuresiMiddleware> logger)
{
    public async Task InvokeAsync(HttpContext context)
    {
        var sw = Stopwatch.StartNew();
        await next(context);
        sw.Stop();
        logger.LogInformation("{Metot} {Yol} {Durum} {Sure} ms",
            context.Request.Method, context.Request.Path,
            context.Response.StatusCode, sw.ElapsedMilliseconds);
    }
}

app.UseMiddleware<IstekSuresiMiddleware>();

Middleware sınıfları uygulama boyunca tek örnek olarak oluşturulur; scoped servisleri kurucuda değil, InvokeAsync parametresi olarak almak gerekir. Servis ömürleri için bkz. dependency injection.

Middleware mi, filtre mi?

MiddlewareFiltre (MVC/endpoint filter)
KapsamTüm isteklerBelirli uç noktalar
BilgiHTTP düzeyiModel, action ve parametreler
ÖrnekLoglama, güvenlik başlıkları, hız sınırlamaDoğrulama, belirli uç noktaya özel kurallar

Genel ve uygulama çapındaki işler middleware'e, uç noktaya özgü işler filtrelere uygundur.

Yerleşik middleware'lerden yararlanın

Hız sınırlama, yanıt sıkıştırma, çıktı önbelleği, sağlık kontrolleri ve hata işleme gibi özellikler zaten yerleşik gelir. Kendi çözümünüzü yazmadan önce bunlara bakın. Bkz. rate limiting, health checks ve performans optimizasyonu.

Sık sorulan sorular

Minimal API'lerde de middleware kullanılır mı?

Evet. Hat yapısı aynıdır; Minimal API uç noktaları da bu hattın sonunda çalışır. Bkz. Minimal API.

Middleware içinde yanıt gövdesini değiştirebilir miyim?

Mümkündür ama dikkat ister; yanıt bir kez gönderilmeye başladıktan sonra başlıklar değiştirilemez.

Sonuç

Middleware hattı, ASP.NET Core uygulamasının omurgasıdır. Doğru sıralama ve yerinde kullanılan özel middleware'ler; güvenlik, loglama ve performans gibi ortak ihtiyaçları tek bir yerde, temiz şekilde çözer.