.Net Core Middleware Yapısı
Middleware yapısı nedir sorusuna uygulamamızın HTTP request ve responselarını nasıl ele alacağımızı belirleyen yapıdır diyebiliriz. Örneğin, bir request uygulamamıza gelirken hata durumunda neler yapılacak? kimlik doğrulaması yapılmış mı? belirli statik dosyalara erişim olacak mı? loglanacak mı? gibi request ve response üzerindeki işlemler middlewarelar ile yapılır. Middlewareların yaptığı iş genel olarak; gelen requestler üzerinde sırasıyla birer logic uygulayıp bir diğer middleware’a göndermektir. Böylece requestleri rahatlıkla yönetebiliriz. Her middleware’ı bir class nesnesi olarak düşünebiliriz. Uygulamamıza gelen her request sırasıyla middlewareların üzerinden geçer.
Middleware bileşenleri Startup.cs classının Configure metodunda belirlenir. Middleware bileşenleri ASP.NET’teki HttpModule’lere benzetebileceğimiz yapılar. Middlewareları Configure metodunun app parametresi üzerinden çağırırız. Aşağıda her requestin geldiğinde öncelikli olarak authentication middlewareı üzerinden geçeceği daha sonra da hemen aşağısındaki middlewarelar üzerinden geçeceği belirtilmiştir. Middleware metot isimleri genellikle Use ile başlatılır.
public void Configure(IApplicationBuilder app, IHostingEnvironment env ) { app.UseAuthentication(); app.UseLogRequest(); app.Run(async (context) => { await context.Response.WriteAsync("cagatay"); }); }
Aşağıda örnek olması açısından configure metodunun içerisine 3 adet middleware çağırılmıştır. Uygulamaya gelen her request sağ taraftaki gibi sırasıyla middlewarelar üzerinden geçer ve uygulama çalıştıktan sonra response da sırasıyla middlewarelar üzerinden döner.
CUSTOM MIDDLEWARE YAZMA
Bu özelliklere ilaveten tabi ki gelen request üzerinde belli işlemler yapmak istersek kendimiz de custom middleware yazabiliriz. Middleware yazmanın farklı yolları olduğu gibi ben kendime kolay gelen middleware yazma şeklini aşağıda kısaca açıklayacağım.
Custom middleware için bir class oluşturup aşağıdaki gibi bir yapı oluşturmamız yeterlidir. Aşağıda class içerisindeki invoke metodu içerisinde requestler üzerinde uygulanacak iş mantığını barındıracak olup middleware çağrıldığında otomatik tetiklenecek fonksiyondur. Constructor içerisinde inject edilmiş RequestDeletage nesnesinin Invoke metodu ile de middleware pipeline’ında bir sonraki middleware’ı çağırır ve httpContextimizi ona devrederiz.
public class SampleMiddleware { private readonly RequestDelegate _next; public SampleMiddleware(RequestDelegate next) { _next = next; } public async Task Invoke(HttpContext httpContext) { //iş mantıgı.. //bir sonraki middlewarei çağırır.. await _next.Invoke(httpContext); } }
Middleware’ı pipeline’a dahil etmek için de startup classının configure metoduna aşağıdaki kod satırını eklemek yeterli olacaktır.
app.UseMiddleware<SampleMiddleware>();
Anlaşıldığı üzere middleware ile request ve response üzerinde işlemler yapıp request ve response’u handle edebiliriz. Request ile etkileşime geçmek için kullanılan 3 tip metot vardır.
- Use
- Run
- Map
– Use Metodu
Bu yöntem size aşağıda da görüldüğü üzere next adında bir delegate sunar. Bununla bir sonraki sırada gelen middleware üyesine erişim sağlayabiliriz. 2 middleware nesnesinin arasına girmek amaçlı kullanılabilir.
app.Use(async (context, next) => { Debug.WriteLine("Use Middleware (Start)"); await next.Invoke(); Debug.WriteLine("Use Middleware (End)"); }); app.Run(async context => { Debug.WriteLine("app.Run"); await context.Response.WriteAsync("Response"); });
Output aşağıdaki gibi olacaktır.
– Use Middleware (Start)
– app.Run
– Use Middleware (End)
– Run Metodu
Run ile pipeline üzerinde short circuit(kısa devre) yapmak mümkündür. Request bu metoda düştükten sonra pipeline üzerindeki diğer işlemler devam etmez ve diğer middlewarelar üzerinden geçmez.
app.Run(async context => { await context.Response.WriteAsync("First Middleware"); }); app.Run(async context => { await context.Response.WriteAsync("Second Middleware"); });
Buradaki kod bloğunda First Middleware yazısının ekrana yazıldığını ve diğer run metoduna düşmeden sonlandığını görebiliriz.
– Map Metodu
Map ile adından da anlaşılacağı üzere bir path yakalamak istediğimiz zaman kullanırız. Aşağıdaki gibi branch isimli map için bir iş mantığı yerleştirmek istediğimizde aşağıdaki gibi bir yol izleyebiliriz.
app.Map(new PathString("/Branch"), _configuration => { _configuration.Run(async context => { await context.Response.WriteAsync("Response"); }); });
Tadında ve tatmin edici bir yazı emeğinize sağlık
Bilgiler için teşekkürler ayrıca net coredaki middleware yapısıyla .netteki bir çok aspect yapısı middleware’e taşınabilir oldu.
Teşekkür ederim, sade bir anlatım olmuş