Node.Js – Middleware

Node.Js Giriş yazısından sonra middleware kavramı ile yazılarıma devam ediyorum..

Middleware kavramının tam bir tanımı olmamakla birlikte genel olarak; geliştirici ile sistem arasında bulunan katmandır. Sistem derken ya işletim sistemi ya da Node altyapısı olan sistemi kasteder.
Daha spesifik olarak middleware katmanı kendisini uygulama ile sistem arasında iletişim katmanı olarak atamaktadır.

Middleware katmanı olmadan uygulama geliştirirsek tüm request işlemi tek ve uzun bir request handler ile yönetilecektir. Middleware yapısı sayesinde request handler parçalara bölünüp, her parçada farklı bir iş yapmamızı sağlar. Middleware kullanarak yapabileceklerimiz;authorization, proxies, routers, cookie ve session yönetimi. Örneğin ilk middleware yapısı log işlemi olsun ve tüm istekler console üzerinden görüntülensin. Bir sonraki middleware olarak authentication olsun ve yetkisi olmayan kullanıcılar daha sonraki middleware katmanına geçemesin.

nodemiddleware

Normal node yapısında middleware yapısı yukarıdaki resimdeki gibi işlemektedir. Client istek yapar. Node http server bu isteği yazdığımız handler function yapısına iletir. Handler içerisinde istek işlenir ve http server’a tekrar yollanır.

Connect ve Express frameworkleri kullanarak işlemlerimizi kısaltmaktayız. Bu yazıda express frameworkten fazla bahsetmeden middleware yapısını anlatmak istiyorum. İkisi arasındaki farka değinecek olursak Connect framework ile sadece middleware işlemine odaklanabiliriz. Express framework kullanırsak daha kapsamlı işler yaparız (routing, view rendering vs). Express, connect framework ile uyumludur. Express kullanırken middleware fonksiyonlarını kendimiz yazabiliriz veya hazırda bulunan geliştiriciler tarafından yazılımış açık kaynaklı module yapılarını kullanabiliriz. Aşağıdaki yapı express middleware yapısını göstermektedir.

expressmiddleware

Node http server üzerinden giden istekler stack yapısında toplanır. Stack yapısı içerisinde istek middleware fonksiyonlarını teker teker işleyip sonunda respond olarak http server’a kullanıcı isteğinin cevabını döndürür. Stack aşamasında middleware yapıları işlenirken herhangi bir hata oluştuğu durumda işlem sırası kesilip hata middleware yapısına geçilmektedir. Kısaca özetlersek express frameworkte gelen istek stack yapısı üzerinden yukarıdan aşağıya doğru tüm middleware işlemlerinden geçer.

 

Middleware fonksiyonları 3 parametre almaktadır. Request ve response sürekli bulunmalıdır. Bunlar: function logger(request,response, next). Hata middleware yapısı ise 4 parametre alır. err, request, response, next 

Örnek verecek olursak; logger yaparken, console.log ile basit bir logger yapısı yaparız. Eğer logger işlemini gerçekleştirmek için hazırlanmış “morgan” adı verilen module yapısını kullanırsak işlemimizi kısaltırız. Sonuçta tekerleği yeniden icat etmemize gerek yok hazır geliştirilmiş modülleri kullanıp yapacağımız işe odaklanmak daha mantıklıdır.

Express.js, middleware yapısını kendi sitesinde basitçe anlatmış. Kısaca özetleyecek olursak. Önceden yüklenmiş(npm install express –save) express modulünü ekliyor ve app değişkenine express uygulamasını tanımlıyor. Mylogger ile basitçe log yapısı oluşturup next() metodu ile bir sonraki yapıyı çağırıyor. app.use(myLogger) ile stack yapısına ekleme işlemi yapılıyor. Ardından routing işlemi yapılarak “/” yani açılışta gösterilecek ilk ekrana “hello world” yazdırıyor.

ekran-alintisi

ekran-alintisi2

Middleware yapısı hakkında bilgi vermeye çalıştım. Nodejs giriş yazısında kaynakçaya eklediğim linklerde daha detaylı bilgi bulabilirsiniz.

Bu makalede aslında express’e kısaca giriş yapmış olduk. Bir sonraki yazımda express framework hakkında yazacağım. Node.Js kullanarak yapacağım örnekleri siteye eklemeyi düşünüyorum.

Advertisements

Node.Js Giriş

Node.Js ile ilgili yazı serisi yazmaya başlıyorum. Uzun zamandır yazmayı düşündüğüm bir konu hakkında kendimi geliştirirken buradan paylaşmanın güzel olacağını düşündüm.

Kısaca tanımlayacak olursak; Javascript üzerinde server-side uygulamalar yazmamızı sağlayan bir framework’dür.

Kendi sitesinde kullandığı tanım;

Node.js® is a JavaScript runtime built on Chrome’s V8 JavaScript engine. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient. Node.js’ package ecosystem, npm, is the largest ecosystem of open source libraries in the world.

Sitesinde ve birçok kaynakta nasıl kurulduğu ve npm ile paket yönetimi nasıl yapılır detaylı anlatılmaktadır. Uzunca nasıl kurulduğu hakkında yazı yazmaktan ziyade Node.Js’nin sağladığı faydalardan başlayalım.

Chrome web browserlarının da üzerinde çalıştığı V8 engine yapısını kullanmaktadır. V8 kullanması hız ve performans artışı sağlamaktadır. Tanımda belirtildiği gibi I/O ve network işlemlerini non-blocking olarak çalıştırmaktadır. Yani herhangi bir işlemin bitmesini beklemeden diğer event ile ilgili işlem başlamaktadır. Örneğin veritabanı sorgusunun sonucu beklemeden başka bir işleme geçilmektedir. Böylece performans artışı önemli bir biçimde görmülmektedir. Real-time ( gerçek zamanlı ) uygulamalar yaparken tüm kullanıcılara aynı anda bilgi akışı sağlanmaktadır.

threading_node

Resimde görüldüğü gibi clientlar tarafından request yapılmaktadır. Event loop yapısı içerisinde istekleri değerlendirip işlemektedir. Non-blocking yapısı sayesinde herhangi bir bekleme olmamaktadır.

Başta Linkedin ve paypal olmak üzere önemli firmalar tarafından kullanılmaktadır.

1 – Asynchronous(Asenktron) ve Event-driven(Olay tabanlı): browser

Node server-side ve client side için event driven ve asenkron bir yapı sunmaktadır. I/O işlemleri yaparken non-blocking yapısı vardır.

Async I/O: Mevcut işlem bitmeden diğer yapılmak istenilen işlemlerin halledilmesine olanak sağlar.

Browser üzerinde non-blocking yapı aşağıda gösterilmiştir. Belirtilen json dosyasından verileri okuma işlemi devam ederken farklı bir request yapabilmekteyiz. I/O işlemi event loop dışında gerçekleşmektedir. Veri okuma işlemi bitince callback fonksiyonu çağrılıp console.log ile veriler ekrana basılıyor.

nonblockingbrowser

Browser daha esnek bir yapıya kavuşuyor. Pek çok istek aynı anda işlenebiliyor.

2 – Asynchronous(Asenktron) ve Event-driven(Olay tabanlı): server

var result = query(“SELECT * FROM table”) syntax’a dikkat etmden bir db sorgusunu temsilen yazalım. Bu işlemi normal şekilde tanımlarsak, tüm veriler okunmadan diğer işlemler dikkate alınmayacaktır. Blocking I/O yapısı vardır.

Bu sorunu çözmek için multithread yapı kullanırsak, bir süre sonra multihreadleri kontrol etmek zorlaşabilir. (örn Apache). Thread sayısı arttıkça context switch işlemi artacaktır. Dolayısıyla ciddi bir performans kaybı yaşanacaktır.

Farklı bir çözüm olarak non-blocking yapı kullanıp aynı anda birçok request talebi işlersek daha esnek bir yapı oluşacaktır. (örn NGINX) Tek thread kullanmasına rağmen apache’ye göre daha hızlı şekilde istekleri değerlendirir.

nginx-apache-reqs-sec

Node içerisinde, I/O işlemleri her zaman event loop dışında gerçekleşmektedir. Server’ın esnek ve kullanışlı olmasını sağlar. (örnek nginx (3x daha hızlı) )

3 – DIRTy uygulamalar ( data intensive real time ) 

Server tarafında gerçekleşen değişikliklerin client tarafında sayfa yenilemeden anlık olarak gösteren uygulamalardır. Birden fazla istek aynı anda gerçekleştirilebilir. Node DIRTy uygulamaları desteklemektedir. Browser ve server arasında tutarlılık sağlanır.

İlk node.js yazısını kısa bir hello world örneği ile bitirelim. server.js adında dosya oluşturup aşağıdaki kodları yazalım.

Cmd ekranında ilgili klasöre gelip. “node server.js” yazıp serverı çalıştırırız.

Ardından browser üzerinden localhost:3000 adresini açarsak ekranda hello world yazısı gözükecektir.

Node.Js’e kısaca tanıtmış olduk. Daha detaylı öğrenmek isteyenler kaynakçada bulunan linklere bakabilirler. Özellikle kitapları ücretsiz olarak pdf biçiminde bulabiliyoruz.

Kaynakça