Derinlemesine yazılım eğitimleri için kanalımı takip edebilirsiniz...

.NET 6 – WebApplication İle Middleware Pipeline’ını İnceleyelim

Merhaba,

Bu içeriğimizde .NET 6’da ki WebApplication nesnesinin arkasındaki koda bakacak, middleware ve endpointlerin nasıl yapılandırıldığına odaklanıyor olacağız.

Önceki .NET 6 – WebApplicationBuilder’ı İnceleyelim başlıklı makalede açıklandığı gibi uygulama yapılandırmasının yapıldığı yer çoğunlukla WebApplicationBuilder‘dır.

WebApplication ise üç ayrı işlev için operasyonel sorumluluk üstlenmektedir;
.NET 6 - WebApplication İle Middleware Pipeline'ını İnceleyelim

  1. IApplicationBuilder arayüzünü uyguladığı için middleware pipeline’ı burada şekillendirilip, yapılandırılmaktadır. Yani middleware şeması bu nesne üzerinden çıkarılmakta ve tetiklenme sıralaması bu nesne üzerinden ayarlanmaktadır.
  2. IEndpointRouteBuilder arayüzünü uyguladığı için MapGet, MapRazorPages vs. gibi metotlar aracılığıyla endpointler yapılandırılmaktadır.
    var builder = WebApplication.CreateBuilder(args);
    var app = builder.Build();
    
    app.MapGet("/", () => "Hello World!");
    
    app.Run();
    
    
  3. IHost arayüzünü uyguladığından dolayı Run metodu eşliğinde uygulama başlatılmaktadır.

.NET 6 - WebApplication İle Middleware Pipeline'ını İnceleyelimWebApplicationBuilder nesnesinin Build metodu tetiklendiğinde bir generic host instance’ı oluşturulur ve bu WebApplication türünde geri döndürülür.

WebApplication Nesnesi Başlatma ve Middleware Pipeline’ı Oluşturma

Web uygulamasını başlatmanın standart yolu WebApplication nesnesi üzerinden Run() ya da RunAsync() metotlarından birini çağırmaktır. Bu metotlar nihai olarak IHost.StartAsync metodunu tetikler ve böylece aşağıdaki görseldeki karmaşık metot etkileşimlerinin başlamasına vesile olurlar.
.NET 6 - WebApplication İle Middleware Pipeline'ını İnceleyelim
Yukarıdaki şemada görüldüğü üzere Host’un ayağa kaldırılması sırasının bir parçası olarak IHostedService çalıştırılmaktadır. Bu middleware’in oluşturulduğu ve Kestrel sunucusunun dinlenmeye başlandığı zamandır.

Aynı şekilde görseldeki GenericWebHostService ise middleware pipeline’ının oluşturulduğu ve uygulamanın çalıştırılmak için Kestrel’e gönderildiği yerdir.

Bu süreç açısından, WebApplication‘ı generic host ile karşılaştırırsak eğer herhangi bir fark bulunmamaktadır.

WebApplication Middleware Pipeline

WebApplication generic host’a kıyasla çeşitli middleware’ler barındırmaktadır. WebApplicationBuilder ise varsayılan olarak Kestrel sunucusunu yapılandırır, HostFiltering Middleware‘ini ekler ve IIS entegrasyonunu etkinleştirir. Bunlara ek olarak WebApplicationBuilder nesnesi ekstradan middleware yapılanmasını kurar.

Şimdi bir Asp.NET Core uygulamasında middleware yapılanmasının nasıl kurulduğunu adım adım inceleyerek devam edelim.

  • Empty(Boş) Pipeline
    Öncelikle uygulamaya herhangi bir middleware veya endpoint eklemeksizin incelemede bulunarak başlayalım.

    Aşağıdaki kod bloğunu incelerseniz eğer;

    var builder = WebApplication.CreateBuilder(args);
    var app = builder.Build();
    app.Run();
    

    Bu kod, kurulumun en temelidir ve aşağıdaki middleware pipeline’ı ile işlemektedir.

    • HostFilteringMiddleware
    • DeveloperExceptionPageMiddleware
    • WebApplication nesnesinin ApplicationBuilder property’sinden oluşturulmuş bir middleware

    .NET 6 - WebApplication İle Middleware Pipeline'ını İnceleyelimYukarıdaki middleware pipeline’ını yandaki gibi şemalaştırabiliriz. Burada DeveloperExceptionPageMiddleware‘inin artık development ortamında otomatik olarak eklendiğine dikkatinizi çekerim.

    Açıkçası varsayılan middleware’e sahip bir uygulama pek kullanılmamaktadır. Haliyle temeli bu şekilde attıktan sonra biraz middleware ekleyerek gözlemlerimize devam edelim.

  • Ekstra Middleware’e Sahip Uygulama
    Şimdi aşağıdaki gibi varsayılan yapının üzerine birkaç middleware ekleyerek gözlemlemede bulunalım.

    var builder = WebApplication.CreateBuilder(args);
    var app = builder.Build();
    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.Run();
    

    Yukarıdaki çalışmada default olan üç middleware’in üzerine ‘UseHttpsRedirection’ ve ‘UseStaticFiles’ middleware’leri eklenmiştir. Haliyle son durum aşağıdaki gibidir;

    • HostFilteringMiddleware
    • DeveloperExceptionPageMiddleware
    • Aşağıdakileri içeren WebApplication nesnesi;
      • HttpsRedirectionMiddleware
      • StaticFilesMiddleware

    .NET 6 - WebApplication İle Middleware Pipeline'ını İnceleyelim

  • Endpoint Tanımlama
    var builder = WebApplication.CreateBuilder(args);
    var app = builder.Build();
    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.MapGet("/", () => "Laylaylom galiba sana göre sevmeler...");
    app.Run();
    

    Yukarıdaki gibi MapGet metodu ile eklenen endpoint’ler, WebApplication nesnesinin endpoint datasources koleksiyonuna eklenmektedirler.
    .NET 6 - WebApplication İle Middleware Pipeline'ını İnceleyelimVe nihai olarak EndpointMiddleware‘i eklenerek middleware pipeline ayağa kaldırılmaktadır.

    • HostFilteringMiddleware
    • DeveloperExceptionPageMiddleware
    • Aşağıdakileri içeren WebApplication nesnesi;
      • HttpsRedirectionMiddleware
      • StaticFilesMiddleware
    • EndpointMiddleware

    .NET 6 - WebApplication İle Middleware Pipeline'ını İnceleyelim

  • UseRouting Middleware
    Burada UseRouting(RoutingMiddleware) middleware’ini incelememizin sebebi, bazı middleware’lerin UseRouting‘den önce çağrılması gerektiğidir. Haliyle RoutingMiddleware’inden önce çağrılması gereken bir middleware varsa ne yapılması gerekmektedir? gelin inceleyelim…

    Bunun için yapılması gereken tek şey UseRouting middleware’inin açıkça çağrılıp, devreye sokulmasıdır.

    var builder = WebApplication.CreateBuilder(args);
    var app = builder.Build();
    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseRouting();
    app.MapGet("/", () => "Laylaylom galiba sana göre sevmeler...");
    app.Run();
    

    Böylece ilgili middleware’ler aşağıdaki gibi şekillenecektir.

    • HostFilteringMiddleware
    • DeveloperExceptionPageMiddleware
    • Aşağıdakileri içeren WebApplication nesnesi;
      • HttpsRedirectionMiddleware
      • StaticFilesMiddleware
      • RoutingMiddleware
    • EndpointMiddleware

    .NET 6 - WebApplication İle Middleware Pipeline'ını İnceleyelim
    UseRouting middleware’i yazıldığında ana/main middleware pipeline’ı ile WebApplication nesnesinin ApplicationBuilder pipeline’ı arasında genel düzenin korunması için WebApplicationBuilder bir işlevsellik göstermektedir. Bu işlevsellik, genel düzeni korumak üzere generic host’a dönmek gerektiğinde ortaya çıkacaktır.

  • UseEndpoint Pipeline
    EndpointMiddleware, MapGet vs. gibi metotlar eşliğinde ya da WebApplicationBuilder nesnesi ile otomatik ekleniyor olasa da UseEndpoints metodu eşliğinde de manuel bir şekilde çağrılarak, eklenebilmektedir.

    var builder = WebApplication.CreateBuilder(args);
    var app = builder.Build();
    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseRouting();
    app.MapGet("/", () => "Laylaylom galiba sana göre sevmeler...");
    app.UseEndpoints(endpoint => endpoint.MapGet("/x", () => "doldur be meyhaneci boş kalmasın kadehim"));
    app.Run();
    

    Haliyle yukarıdaki inşa ile aşağıdaki middleware yapılanması elde edilecektir.

    • HostFilteringMiddleware
    • DeveloperExceptionPageMiddleware
    • Aşağıdakileri içeren WebApplication nesnesi;
      • HttpsRedirectionMiddleware
      • StaticFilesMiddleware
      • RoutingMiddleware
      • EndpointMiddleware
    • EndpointMiddleware

    .NET 6 - WebApplication İle Middleware Pipeline'ını İnceleyelimYukarıdaki davranış ile endpoint’leri doğrudan hem WebApplication‘da hem de EndpointMiddleware‘in çağrısında kaydetmiş oluyoruz.

    Burada dikkat edilmesi gereken önemli bir nokta vardır, o da; UseEndpoints middleware’i manuel kullanılıyorsa kesinlikle UseRouting middleware’i de manuel çağrılmalıdır. Aksi taktirde hata alınacaktır.

Nihai olarak;
WebApplication nesnesi üzerinden yapılan çalışmalarda middleware pipeline’ının nasıl ve ne şekilde oluşturulduğunu görmüş ve incelemiş olduk. Böylece artık .NET 6 ile geliştirilen web uygulamalarında, konfigürasyon yapılanmasında neyin ne olduğuna ve ne şekilde davranış sergilediğine tam olarak vakıf bir şekilde geliştirmeler yapabilir ve nimetlerinden daha bilinçli faydalanabiliriz.

İlgilenenlerin faydalanması dileğiyle…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…

Bunlar da hoşunuza gidebilir...

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir