Express.js – Middleware(Ara Katman) Nedir? Nasıl Kullanılır?
Merhaba,
Yazılım dendimi akıllara kompleks ve anlamsız işlemlerden anlamlı sonuçlar üreten bir olgu gelmektedir. Bu kompleks süreçler, son kullanıcılara mümkün mertebe yansıtılmadan programın hizmet edeceği iş ne ise o alana dönük olabildiğince tüm işlemler arayüz odaklı halledilebilir hale getirilmektedir. Tabi süreci sadece son kullanıcı odaklı düşünürsek ilgili yazılımda nihai erişimi arayüzsel seviyede yönetilebilir hale getirmek yeterli olacaktır. Lakin bu işin bir de yazılım geliştiricileri boyutu mevcuttur. Yani kompleks sürecin tam merkezinde yani işin kod ve veri kısmında bulunan yazılım ekibi bu süreci kendi lehlerinde anlamlandırabilirlerse, hem geliştiriciler için hem de yazılımın geleceğe dair gelişimindeki eğilimi için oldukça faydalı katkıda bulunulmuş olacaktır.
Aslında bu anlamlandırma uğraşısı, yazılımın sağlam temellerde inşa edilmesini sağlayacağından dolayı doğru, prensipli ve anlaşılabilir kod inşaasını gerektirecek ve bir yandan da yazılımcılar için projeye hiyerarşik boyut kazandıracak neyin, nerede ve ne amaçla olduğuna dair daha geniş perspektifle ilgili projeye bakış açılarını genişletecek ve verimi arttıracaktır. Yani yazılım geliştiriciler ustaysa eğer inşaatta çekicin çivinin nerede nasıl tutulduğunu bilmeleri işlerinde hızlanmalarını sağlayacaktır.
Teknik boyutta bir projeyi daha anlamlı hale getirmek için öncelikle doğru yaklaşımlarla ilgili proje tasarlanmalıdır. Buda doğru ve detaylı plan gerektirmektedir. Tasarıya dönük olması gerektiği yerlerde ise bir Çinli ile bir başka Aborjin yazılım geliştiricinin birbirlerinin beşeri dillerini bilmeden, birinin yaptığı işi bir diğerinin tek bakışta ve tek seferde anlayabilmesini sağlayacak olan design pattern(tasarım desenleri) yapıları uygulanmalıdır. Tüm bunların yanında proje mümkün mertebe katmansal hale getirilmeli ve tekrardan dünya standartlarında bir katmanlı mimarinin eşliğinde proje temellendirilip ihtiyaca dönük özel katmanlarla genişletilmelidir.
Bu içeriğimizde bizler bir projenin katmansal hale getirilmesini Node.js’in Express.js modülünde küçük bir noktada değerlendirecek ve gelen requestlere karşılık response gönderilmeden araya Middleware şeklinde isimlendirilen ara katman sokacağız. Şimdi gelin Middleware’in ne işe yaradığını ve nasıl kullanıldığını inceleyelim.
Middleware(Ara Katman) Nedir?
Klasik web uygulamalarında, kullanıcıdan gelen taleplere(request) karşılık cevaplar(response) gönderilmektedir.
Gelişmiş yapılanmada ise, request – response işlevsel ilişkisinin arasına Middleware girebilmekte ve tek elden ek işlemler icra edilebilmektedir.
Middleware katmanı, genellikle tüm route rotalarında yapılacak işlemleri tek elden yönetmek için kullanılmaktadır. Genellikle bu işlemlerden biri kullanıcı oturum kontrolüdür. Her bir route üzerinde bu kontrolü yapmanın ne kadar maliyetli ve lüzumsuz kod israfına yol açacağını siz düşünün…
Şimdi Middleware ile ilgili teknik boyutta değerlendirmelere başlayalım.
const express = require("express"); const app = express(); app.use((request, response, next) => { response.send("Middleware çalıştı."); }); app.get("/", (request, response) => { response.send("Route çalıştı..."); }).listen(5000);
Yukarıdaki kod bloğunu incelerseniz eğer “app.use” fonksiyonu içerisine tanımlanan callback fonksiyonu ile Middleware’i oluşturmuş oluyoruz. Bu işlemden sonra “app” üzerinden oluşturulan tüm route yapıları için herhangi bir istek söz konusu olursa bu istek karşılığında cevap verilmeden önce ilgili middleware devreye girecektir.
“Tamam, istek neticesinde ilgili middleware devreye girdi girmesine ama sanki tetiklenen route çalıştırılmadı la hoca!” diye söyleniyor olabilirsiniz… Evet, haklısınız. Ama bu sorunuzun cevabına gelmeden önce middleware fonksiyonumuzdaki parametrelerden en sonuncusu olan “next” fonksiyonunu inceleyelim.
“next” parametresi yukarıda bahsettiğim gibi bir fonksiyondur. Bu fonksiyon çağrıldığı zaman ilgili middleware’de ki çalışmaların onaylandığı bir başka deyişle doğrulandığı söz konusu olacaktır ve middleware tetiklenmeden önce hangi route’a istek gönderildiyse o route bu doğrulama neticesinde çalıştırılacaktır.
Bu mantıkla yukarıdaki çalışmaya göz atarsak eğer “next” fonksiyonu çağrılmadığı için ilgili tetiklenen route çalıştırılmamıştır.
const express = require("express"); const app = express(); app.use((request, response, next) => { next(); }); app.get("/", (request, response) => { response.send("Route çalıştı..."); }).listen(5000);
Bu şekilde “next” fonksiyonunu tetiklersek direkt olarak route tetiklenecektir.
Şimdi örneğimizi daha da derinleştirerek konumuzu detaylandırmak için bir kullanıcı oturum kontrolü sağlayalım.
const express = require("express"); const app = express(); app.use((request, response, next) => { let isLogin = false; if (isLogin) next(); else response.send(`${request.url} middleware çalıştı.<br> Kullanıcı girişi yapılmadı.`); }); app.get("/", (request, response) => { response.send("Anasayfa"); }).get("/profil", (request, response) => { response.send("Profil sayfası."); }).get("/ayarlar", (request, response) => { response.send("Ayarlar sayfası."); }).listen(5000, () => console.log("Yayın başladı..."));
Yukarıdaki kod bloğunu incelerseniz eğer “/”, “/profil” ve “/ayarlar” adreslerine olmak üzere üç adet route oluşturulmuştur. Bu routelara yapılan isteklerde middleware devreye girecek ve kullanıcı oturum kontrolü yapacaktır. Eğer oturumu açıksa ilgili sayfalara yönlendirecektir.
Gördüğünüz gibi biz manuel olarak oturumu false değerinde tuttuğumuz için hiçbir route’a erişim gerçekleştirilememektedir.
Eğer ki bir middleware katmanının sade ve sadece istediğiniz bir route rotasında uygulanmasını istiyorsanız aşağıdaki gibi çalışma gerçekleştirebilirsiniz.
. . . app.use("/profil", (request, response, next) => { let isLogin = false; if (isLogin) next(); else response.send(`${request.url} middleware çalıştı.<br> Kullanıcı girişi yapılmadı.`); }); . . .
“use” fonksiyonunun ilk parametresine hangi routeta middleware’ın çalışılmasını istiyorsanız belirtmeniz yeterlidir.
Ayrı Bir Modül Olarak Middleware
Middleware katmanını farklı bir modül olarak tasarlayarak ihtiyaca dönük gereken noktalarda require edebilir ve kullanabiliriz.
//-isLogin.js const isLogin = (request, response, next) => { let isLogin = false; if (isLogin) next(); else response.send(`${request.url} middleware çalıştı.<br> Kullanıcı girişi yapılmadı.`); }; module.exports = isLogin;
Yukarıda görüldüğü üzere modül olarak tasarlanan middleware katmanını aşağıdaki gibi require ederek kullanabiliriz.
. . . const isLogin = require("./isLogin"); app.use(isLogin); . . .
Export edilen modülü require ile elde ettikten sonra “app.use” fonksiyonuna direkt olarak vermemiz yeterlidir.
Modül bazlı çalışırken istenilen route rotasında middleware katmanını kullanmak isterseniz eğer aşağıdaki gibi çalışabilirsiniz.
const express = require("express"); const app = express(); const isLogin = require("./isLogin"); app.get("/", isLogin, (request, response) => { response.send("Anasayfa"); }).get("/profil", (request, response) => { response.send("Profil sayfası."); }).get("/ayarlar", isLogin, (request, response) => { response.send("Ayarlar sayfası."); }).listen(5000, () => console.log("Yayın başladı..."));
Görüldüğü üzere direkt olarak route fonksiyonlarında ikinci parametre olarak ilgili middleware modülünü vermemiz yeterlidir.
Eğer ki middleware modülleri birden fazla ise aşağıdaki gibi bir yaklaşım sergileyebilirsiniz.
. . . const app = express(); const isLogin = require("./isLogin"); const control = require("./control"); app.get("/", isLogin, control, (request, response) => { response.send("Anasayfa"); }) . . .
Dikkat ederseniz eğer route rotasında ilk parametreden sonra istenildiği kadar middleware atanabilmektedir. Buradaki öncelik sıralaması atama sıralamasıyla birebir uyumludur. Yani ilk olarak “isLogin” middleware katmanı kontrol edilecek. Eğer “next” metodu tetiklenirse ardından “control” middleware katmanı denetlenecektir. Ve bu işlem atanan n adet katman için bu şekilde devam edecektir.
Bir yazımızın daha sonuna gelmiş bulunmaktayız. Umarım bol bol faydalanırsınız.
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar dilerim…
tesekkur ederim hocam.
cok sade ve anlasirilir bir aciklama
Faydalandıysanız ne mutlu…
Hocam gördüğüm en sade net Türkçe güzel kaynaklar tüm site içeriğiniz için geçerli çok teşekkür ederim çabanız için.
Teşekkür ederim Yunus Bey. Beni çok mutlu ettiniz. Bol bol faydalanmanız dileğiyle.
Çok teşekkürler hocam sizin kadar anlaşılır anlatan çok az insan gördüm.
Estafurullah… Faydalandıysanız ne mutlu…
İyi çalışmalar.
Hocam çok teşekkürler gerçekten çok bilgilendriici oldu
Faydalandıysanız ne mutlu 🙂
Hocam o ********* kurban
Node.js çalışırken bu blog karşıma sık çıkmaya başladı, anlatımlarınıza hayran kaldım hocam.
Muhakkak fazlasını hakediyorsunuz ama elimden geldiğince her seferinde reklamlara birkaç kez tıklıyorum, diğer arkadaşlara da tavsiye ederim.
Emeğinize sağlık.
Teşekkür ederim 🙂
Ama reklamlara tıklamak gibi bir vicdani sorumluluk duymanıza gerek yok kanaatindeyim 🙂
Faydalanmanız dileğiyle…
Sevgiler…
çok temiz, çok kaliteli bir anlatım. Teşekkürler
Ya birşey söyleyeceğim. sabhatandır 4 5 farklı youtube kanaladından bu middleware konusunu anlamaya çalışıyorum. Ancak sizin yazınızı okuyunca çok daha iyi anladım. Anatıma ek olarak kod örnekleri çok çok iyi. elinize sağlık bunu okuan tüm herkesin adına teşekkür ederim.
O zaman bi de video dersimizi izleyin 🙂
https://www.youtube.com/watch?v=BdNZ9gzsQdg