Herkese merhaba. Bu yazıda .NET web uygulamaları dünyasında çok kullanılan bir yapıdan bahsedeceğim. Middleware; web uygulamamıza gelen HTTP request ve response’ları işleyen ve belli kurallara göre yönlendirme veya sonlandırma yapan bir ara katmandır. Her isteği modüler bir şekilde işleyip yönetmemize olanak tanır. Middleware, yazılım dünyasında Aspect Oriented Programming (AOP) olarak bilinen tasarıma somut bir örnektir. AOP’nin temel amacı olan ‘loglama, güvenlik veya önbelleğe alma gibi ortak işleri tek bir merkezden yönetme’ fikrini, bizim için HTTP istek ve cevap mekanizması üzerinde hayata geçirir. Peki bu sistem tam olarak nasıl çalışır?
Middleware Nedir ve Nasıl Çalışır?

Şemada gördüğümüz üzere client’tan gelen bir request endpoint’e ulaşmadan önce bizim middleware bileşenleri ile oluşturduğumuz pipeline içerisine girer. Her bileşen HTTP requestini alır ve kendi içerisindeki kuralları çalıştırır. Eğer request bu bileşen içerisinden başarılı bir şekilde geçerse bir .next() metodu ile sonraki bileşene aktarılır. En sondaki Application Logic çalışıp bittikten sonra oluşan response, aynı hattı tersten takip ederek yine middleware’ler üzerinden geçer ve client’a ulaşır. Hata alan veya geçerli şartları sağlamayan requestler ise o middleware içerisinde sonlandırılarak (short-circuit) endpointe ulaşmadan geri döner.
Buradaki temel nokta, middleware’in bidirectional (çift yönlü) çalışmasıdır. Yani; await next() öncesindeki kod request yolunda (gelen istekte), sonrasındaki kod ise response yolunda (giden yanıtta) çalışır. Bu sayede bir loglama middleware’i, tek bir component içinden hem gelen request detaylarını hem de giden response’un status code’unu yakalayabilir.
Bir örnek içerisinde bu yapının çalışma sırasını inceleyelim.
app.Use(async (context, next) =>
{
Console.WriteLine("Middleware 1: Incoming request");
await next();
Console.WriteLine("Middleware 1: Outgoing response");
});
app.Use(async (context, next) =>
{
Console.WriteLine("Middleware 2: Incoming request");
await next();
Console.WriteLine("Middleware 2: Outgoing response");
});
app.Run(async context =>
{
Console.WriteLine("Middleware 3: Terminal - handling request");
await context.Response.WriteAsync("Hello, world!");
});
[ApiController]
[Route("[controller]")]
public class MiddlewareController : ControllerBase
{
[HttpGet(Name = "GetResponse")]
public string Get()
{
return "Hello from MiddlewareController!";
}
}


Request geldiğinde sırasıyla 1 ve 2‘nin await next() öncesindeki kodları çalışır. Ardından 3 devreye girer, response’u hazırlar ve döngü geri sarar.
Geri dönüş yolunda önce 2‘nin, ardından 1‘in await next() sonrasındaki kodları çalışır.
Not: app.Run terminal (sonlandırıcı) middleware olduğu için istek controller’a ulaşmadan yanıtlanmış olur.
Faydaları
- Pipeline Kontrolü: Her bileşen requesti başarılı bir şekilde bir sonraki bileşene iletebilir veya sonlandırabilir.
- Bidirectional (Çift Yönlü) İşlem: İçeriğindeki kuralları hem request hem de response için çalıştırabilir.
- Composable (Birleştirilebilir): Program.cs içerisinde
app.Use(), app.Run()veyaapp.Map()olarak kaydedersiniz ve pipeline’ları bloklar halinde üst üste yerleştirebilirsiniz. - Sıra Bağımlılığı: Program.cs içerisinde yerleştirilen bileşenler çalışma sırasını da belirler. Bileşenleri yanlış sıraya koymak buglara neden olabilir.
Middleware basitçe şunu yapar; HttpContext’i al, işlemlerini yap sonrasında ya bir sonraki bileşene ilet veya short-circuit (kısa devre) yaparak bir response oluştur. Eğer short-circuit yapılırsa akıştaki bütün middleware bileşenleri atlanır ve response son çalışmış bileşen üzerinden geri döner.
ASP.NET Core’da her middleware bileşeninin temelini HttpContext ve RequestDelegate oluşturur. RequestDelegate, işlem zincirindeki bir sonraki adımı temsil eden bir fonksiyondur. HttpContext ise o anki HTTP isteğine ve yanıtına dair tüm bilgileri barındırır. Her middleware bu nesneyi işler ve kontrolü RequestDelegate aracılığıyla zincirdeki sonraki bileşene devreder.
ASP.NET Core, uygulamanın temel ihtiyaçlarını karşılamak için birçok hazır (built-in) middleware ile birlikte gelir. Örneğin; kimlik doğrulama, static dosya sunumu, yönlendirme (routing) ve hata yönetimi gibi yaygın işlemler için kendi middleware’lerimizi yazmak yerine framework’ün sunduğu bu hazır bileşenleri kullanırız.
app.UseExceptionHandler();
app.UseRouting();
app.UseCors("AllowFrontend");
app.UseAuthentication();
app.UseAuthorization();
Github repomda bununla ilgili biraz daha günümüz uygulamalarında nasıl kullanıldığını gösteren basit bir uygulama hazırladım. Onu da inceleyebilirsiniz. Bir sonraki yazıya kadar kendinize çok iyi bakın! 😊
Leave a Reply