.Net Core platformuyla birlikte geliştiricilerin yani bizlerin hayatına birçok yeni kavram geldi. Bu yazımızda bu yeni kavramlardan birisi olan “Middleware” yapısına değinmiş olacağız.
Middleware nedir sorusuna geçmeden önce .NET Core öncesinde .NET Framework üzerinde geliştirme yapan insanların aslında bu yapıya çok da yabancı olmadığı söylenebilir. .NET Core öncesinde geliştiriciler Filters yapısını kullanarak Request’lerin öncesinde veya sonrasında araya girerek özelleştirilmiş aksiyonlar alabilmekteydi. Middleware yapısı da aslında bunu hedeflemekte olup geliştiricilere daha modüler bir yapı sunmaktadır. Kısaca Middleware nedir sorusuna cevap verecek olursak; Request/Response Pipeline’ı üzerinde özelleştirilmiş aksiyonlar alınmasını mümkün kılan, bu Pipeline akışının handle edilmesini sağlayan modüler ve etkili yapılardır.
Middleware yapıları, IApplicationBuilder Interface’inden türetilen bir Class’a Extension olarak tanımlanan Method’ların istenilen sırada çalıştırılmasıni sağlayan modüler yapılardır. Bu yapılar ile birlikte;
- Request’lerin istenilen kontrollerden geçirilmesi sağlanabilir,
- Response’ların cache üzerinden türetilmesi sağlanabilir,
- Uygulama üzerinde loglama mekanizmaları oluşturabilir,
- Exception Handling için çözümler sağlanabilir
ve bunlara benzer birçok ihtiyaca yönelik çözümler oluşturulabilir.
Resim – 1
Uygulamada tanımlanmış olan Middleware’ ler Register edilme sırasıyla Resim – 1′ de görüldüğü üzere birbirlerini “next();” Method’u ile çağırarak Request/Response Pipeline’ı tamamlarlar. Ayrıca bir Middleware gelen Request’in bir sonraki Middleware’e geçirilip geçirilmeyeceğini filtreleyebilir, sıradaki Middleware’den önce veya sonra çalışabilir.
Basit bir senaryo ile bu teorik bilgileri kolayca uygulayabileceğimiz bir proje oluşturalım. Senaryoya göre, bir Web API ‘a gelen Request’lerde bulunan Method Type, URL Path ve Response Status Code’ların loglanması istenmektedir. Bu ihtiyacı karşılamak için bir Custom Middleware geliştirmek yeterli olacaktır. Senaryo anlatımı için kullanılacak platform ve IDE aşağıdaki gibidir.
- .NET 5 SDK (https://dotnet.microsoft.com/download/dotnet/5.0)
- Visual Studio Code (https://code.visualstudio.com )
Visual Studio Code Terminal’i üzerinden aşağıdaki komutu kullanarak yeni bir Web API projesi oluşturalım. (Resim – 2)
- dotnet new webapi -n custom-middleware-example
Resim – 2
Oluşturulan proje içerisinde Startup.Configure Method’unu inceleyecek olursak, proje oluşturulduğunda default olarak eklenmiş olan Service’ler ve Middleware’lar bizi karşılamaktadır. Yeni oluşturacağımız Custom Middleware’ı da Register edeceğimiz yer tam da burası olacaktır. (Resim – 3)
Resim – 3
Proje içerisine “LoggingMiddleware.cs” adında bir Class oluşturalım ve bir File’a senaryoda istenilen bilgilerin loglanması için gerekli işlemleri tanımlayalım. (Resim – 4)
Resim – 4
Class içerisinde RequestDelegate Object’ini parametre olarak alan bir Constructor oluşturduk. Bu Object gelen Request’i Handle etmemizi sağlayacak ve gerekli işlemler yapıldıktan sonra HttpContext ile birlikte Request/Response Pipeline’ı üzerinde Request’in hayatına devam etmesini sağlayacaktır.
Yukarıda görüldüğü üzere InvokeAsync Method’u, Middleware’lar çağrıldığında Execute edilecek olan Method’tur. Bu Method, uygulamaya gelen Request’e ve oluşturulan Response’a müdahale edebilmemizi sağlar. Biz de burada senaryo ihtiyacı gereği Request ve Response üzerinden gerekli bilgileri alıp bir log kaydı oluşturduk.
Sonrasında LoggingMiddlewareExtension.cs adında bir class daha oluşturalım. Hazırlamış olduğumuz bu Custom Middleware’ı uygulamaya Register etmek için gerekli tanımlamaları yapalım. (Resim – 5)
Resim – 5
Öncesinde de bahsetmiş olduğumuz gibi IApplicationBuilder tipinde oluşturulan yeni Extension Method’unu da tamamlamış olduk. Şimdi tek yapmamız gereken Startup.Configure Method’u içerisinde Register etmek. (Resim – 6)
Resim – 6
Bu adımdan sonra senaryoyu tamamlamış bulunuyoruz ve çıktıları görmek için projeyi çalıştırabiliriz. .NET 5 ile birlikte yeni bir Web API projesi oluşturduğumuzda, default olarak WeatherForecastController Class’ı bizi karşılamaktadır. Testlerimiz için hazır olan bu Endpoint’i kullanacağız. Projeyi çalıştırdığımızda Request oluşturmak için default olarak gelen Swagger arayüzünü kullanacağız.
- https://localhost:5001/swagger/index.html
Alternatif olarak Postman veya başka bir Tool da kullanılabilir. Senaryoya göre beklentimiz, Web API’a gönderilen her Request için uygun bir log kaydı oluşturulmasıdır.
Resim – 7
Resim – 7 ‘de Swagger arayüzünden de görüldüğü üzere başarılı bir Response bizi karşılamaktadır. Ek olarak aşağıdaki gibi Web API üzerinde bulunmayan bir Endpoint’e Request oluşturalım.
- https://localhost:5001/WeatherForecast/test
Şimdi de log.txt File’ı üzerinden oluşan logları inceleyelim.
Resim – 8
Logları incelediğimizde ilk olarak “/WeatherForecast” Endpoint’ine başarılı bir istekte bulunulduğu görmekteyiz. Sonrasında ise “/WeatherForecast/test” Endpoint’ine bir istekte bulunulduğu ve böyle bir Endpoint olmadığı için Response Status Code olarak 404 değerinin döndüğünü görmekteyiz.
Loglar da incelendiğine göre; senaryoyu başarılı bir şekilde tamamlamış bulunuyoruz. Çalıştığım birçok projede ihtiyaç duyduğumuz çözümleri Middleware yapıları oluşturarak basit ve modüler bir şekilde gerçekleştirdik. Umarım sizler için de faydalı bir paylaşım olmuştur.
Bu konuyla ilgili sorularınızı alt kısımda bulunan yorumlar alanını kullanarak sorabilirsiniz.
Referanslar
https://docs.microsoft.com/en-US/aspnet/core/fundamentals/middleware/?view=aspnetcore-5.0
https://github.com/sertaceren/custom-middleware-logging-example
TAGs: Middleware, Custom Middleware, .Net 5.0, ASP.NET Core, C#, ASP.NET Core MVC, ASP.NET WEB API, Visual Studio Code, VSCode, VS Code