Node.js Middleware Yapısını Anlama
Express ile ilk API'yi yazan herkes aynı satırı görür: app.use(express.json()). Ama o satırın arka planda ne yaptığını bilmeden ilerleyince, bir gün "req.body neden undefined?" ya da "hata mesajım neden hiç dönmüyor?" sorusuyla saatler kaybedilir.
Çözüm basit: middleware zincirini kafanda net bir şekilde canlandırmak. Bir kere oturduğunda, Express'in tamamı anlaşılır hale gelir. Aşağıdaki adımları kendi projende terminal açık şekilde denemen en iyisi.
Middleware Nasıl Çalışır?
Express aslında ince bir katman. İçinde sihir yok; sırayla çalışan fonksiyon listesi var. Gelen her istek bu listenin başından girer, ya sonuna kadar ilerler ya da yolda bir yerde cevaplanır.
İstek zinciri ve next() mantığı
Bir middleware imzası şudur: (req, res, next). Üç ihtimalden birini yaparsın:
- next() çağırırsın → istek sıradaki middleware'e geçer.
- res.json() / res.send() ile cevap dönersin → zincir orada biter.
- next(err) çağırırsın → normal zincir atlanır, hata zincirine düşer.
Hiçbirini yapmazsan istek asılı kalır. Tarayıcı döner döner ve timeout'a girer. Debug ederken ilk bakacağın yer burasıdır: unutulmuş bir next().
Küçük bir logger yazarak test et: app.use((req, res, next) => { console.log(req.method, req.url); next(); }) — bunu en üste koy, her isteği terminalde gör.
Middleware türleri
| Tür | Nasıl bağlanır | Örnek iş |
|---|---|---|
| Uygulama seviyesi | app.use(fn) | Log, CORS, body parse |
| Yol bazlı | app.use('/admin', fn) | Yetki kontrolü |
| Route seviyesi | app.get('/x', fn, handler) | Tek endpoint doğrulaması |
| Router seviyesi | router.use(fn) | Modül bazlı kurallar |
| Hata middleware'i | 4 parametreli fn | Merkezî hata cevabı |
Router seviyesini erken öğrenmek işe yarar. Kullanıcı, ürün, sipariş gibi modülleri ayrı dosyalara böl; her birine kendi middleware'ini ver. Dosya yapısı büyüdükçe fark edilir bir rahatlık sağlar.
Sıralama neden her şeyden önemli
nodejs express middleware yapısında sıra, kodun kendisinden daha kritiktir. Birkaç kural:
- Gövde parser'ları (express.json) route'lardan önce gelmeli. Yoksa req.body boş kalır.
- Auth kontrolü, koruduğu route'lardan önce tanımlanmalı.
- Statik dosya servisi genelde en üstte durur; gereksiz iş yapmayı önler.
- 404 yakalayıcı tüm route'lardan sonra gelir.
- Hata middleware'i her zaman en son satırdır.
Bir dosyayı yukarıdan aşağı okurken zinciri hayal et. Bu alışkanlık, JavaScript performans konularında da işine yarar: gereksiz katman, her istekte ödediğin bir maliyettir.
Custom Middleware ve Hata Yönetimi
Kendi middleware'ini yazmak, hazır paketleri ezberlemekten daha öğreticidir. Üç tipik ihtiyaçla başla.
1. Doğrulama middleware'i
Gelen veriyi route'a girmeden kontrol et. Böylece handler sadece iş mantığıyla ilgilenir.
- Fonksiyonu ayrı dosyada tut: middlewares/validateUser.js
- Eksik alan varsa res.status(400).json({ error: 'email zorunlu' }) döndür.
- Her şey uygunsa next() çağır.
- Parametre alan versiyon istiyorsan fonksiyon döndüren fonksiyon yaz: validate('email') gibi.
2. Auth ve req üzerine veri taşımak
Middleware'ler req nesnesini zenginleştirebilir. Token'ı çözdükten sonra req.user = payload yazarsan, sonraki tüm handler'lar kullanıcıyı bilir.
- Header'dan Authorization değerini al, "Bearer " kısmını ayır.
- Token geçersizse next(new Error('...')) yerine 401 dönmek daha nettir.
- Şifre ve token saklama tarafında ayrı bir disiplin gerekir; güvenli şifre saklama yöntemlerini ayrıca çalış.
3. Hata middleware'i ve async tuzağı
Express hata middleware'ini parametre sayısına göre tanır. Dört parametre yazmazsan normal middleware sanılır:
app.use((err, req, res, next) => { console.error(err); res.status(err.status || 500).json({ error: err.message }); })
Dikkat edilmesi gerekenler:
- Senkron kodda atılan hatayı Express otomatik yakalar.
- Async fonksiyonda yakalamaz. try/catch içine al ve catch bloğunda next(err) çağır.
- Tekrarı azaltmak için bir wrapper yaz: asyncHandler(fn) = (req,res,next) => Promise.resolve(fn(req,res,next)).catch(next)
- Hata nesnesine status ve code alanları ekle; istemci tarafı ayrıştırmayı kolaylaştırır.
- Kullanıcıya stack trace gösterme; sadece log'a yaz.
Yazdıklarını doğrulamak için farklı senaryolar dene: eksik gövde, bozuk token, olmayan endpoint. REST API test etme araçları bu noktada zaman kazandırır; her senaryoyu kayıtlı istek olarak saklayabilirsin.