Menu

Express Middleware Nedir: next() Nasıl Çalışır, Örneklerle

Express middleware, route handler'ından önce çalışan bir (req, res, next) fonksiyonudur. İsteği okuyabilir ya da değiştirebilir, bir response ile bitirebilir ya da iletmek için next() çağırabilir.

Bu sayfada çalıştırılabilir editörler var. Düzenle, çalıştır ve sonucu anında gör.

Express'te middleware, bir isteğin geldiği an ile bir response'un gönderildiği an arasında çalışan, (req, res, next) imzalı bir fonksiyondur. Her middleware req ve res nesnelerini okuyabilir ya da değiştirebilir, bir response göndererek isteği bitirebilir ya da isteği sıradaki fonksiyona vermek için next() çağırabilir. app.use(fn) her istek için bir middleware ekler ve Express her şeyi kaydettiğin sırayla çalıştırır.

Console her istek için üç adımı sırayla yazar ve route, logger'ın eklediği bir property olan req.startedAt değerini okur. GET /missing gönder: iki middleware yine log yazar, çünkü app.use() her path ile eşleşir, sonra hiçbir route eşleşmediği için Express 404 ile cevap verir.

next() çağırmayı unutmak

Ne response gönderen ne de next() çağıran bir middleware isteği asılı bırakır. İstemci zaman aşımına kadar bekler ve log'larda hiçbir şey görünmez, bu da onu yaygın bir middleware hatası yapar. Yukarıdaki logger fonksiyonundan next(); satırını sil ve GET / isteğini tekrar gönder: istek hiç cevap almaz.

Kural basit: bir middleware içindeki her yol bunlardan tam olarak biriyle biter:

  • devam etmek için next(),
  • hata handler'ına atlamak için next(err) (bkz. Express error handling),
  • res.json() ya da res.status(401).send() gibi bir response.

Bir response gönderdikten sonra next() çağırmak da bir hatadır. Sıradaki handler ikinci bir response göndermeye çalışır ve Express ERR_HTTP_HEADERS_SENT fırlatır. Fonksiyon orada dursun diye return res.status(401).json(...) yaz.

İsteği durduran bir auth kontrolü

Bir isteği reddeden middleware response'u kendisi gönderir ve asla next() çağırmaz. Yalnızca o route'u korumak için onu route'a ek bir argüman olarak ver:

İlk istek {"error":"Missing or wrong API key"} ile 401 alır. İstek çubuğuna x-api-key: secret123 header'ını ekle ve tekrar gönder: bu sefer cevap {"users":42,"caller":"reporting-app"} olur. /public kontrolü hiç çalıştırmaz.

Middleware nerede çalışır

YazdığınNe için çalışır
app.use(fn)Her istek, her metot
app.use('/api', fn)/api ile başlayan path'ler
app.get('/admin', fn, handler)Yalnızca GET /admin, handler öncesinde
router.use(fn)O router'ın her route'u

Sıra anlamın bir parçasıdır. Route'lardan sonra kaydedilen bir logger, o route'ların cevapladığı istekleri hiç log'a yazmaz, çünkü response gönderen bir route next() çağırmaz. Logging, body parsing ve CORS gibi uygulama geneli middleware'i önce kaydet, sonra route'ları, en son da 404 ve hata handler'larını.

Yerleşik middleware

Express, app.use() ile ekleyebileceğin birkaç middleware fonksiyonuyla gelir. Body parser'lar req.body değerini doldurur; onlar olmadan bu değer undefined olur.

MiddlewareNe yapar
express.json()JSON body'leri parse eder (Content-Type: application/json)
express.urlencoded()HTML form gönderimlerini parse eder (name=Ada&age=36)
express.text()Düz metin body'yi string olarak req.body içine koyar
express.static('public')Bir klasördeki dosyaları sunar

{"name": "Ada"} body'siyle POST /echo gönder, cevap "body":{"name":"Ada"} içerir. express.json() satırını sil, tekrar gönder ve cevapta body olmadığını gör: req.body değeri undefined olur ve JSON.stringify undefined değerleri dışarıda bırakır. cors, helmet ve morgan gibi paketler de middleware'dir: onları npm install ile kurarsın ve aynı şekilde app.use() fonksiyonuna verirsin. Dosya sunmayı express.static sayfası anlatıyor.

Sık yapılan hatalar

Middleware'i vermek yerine çağırmak. app.use(logger()), logger fonksiyonunu açılışta bir kez çalıştırır ve dönüş değerini kaydeder. app.use(logger) yaz. (express.json() parantezli yazılır, çünkü bir middleware fonksiyonu döndürür.)

Body parser'ı route'lardan sonra eklemek. Route'lar önce çalışır ve req.body değerini undefined olarak görür.

app.use('/admin', fn) ifadesinin tek bir path ile eşleşmesini beklemek. /admin/users ve /admin altındaki diğer her path için, her metotta da çalışır. Tek bir route'u korumak için middleware'i app.get('/admin', fn, handler) şeklinde ver.

Sıkça Sorulan Sorular

Middleware ile route handler arasındaki fark nedir?

Teknik olarak hiçbir şey: ikisi de (req, res, next) fonksiyonudur. Geleneksel olarak route handler isteği bir response ile bitirir, middleware ise genelde ortak bir iş yapar ve next() çağırır.

Middleware async olabilir mi?

Evet. Express 5'te hata fırlatan ya da reject edilmiş bir promise döndüren async bir middleware, hatayı otomatik olarak hata handler'ına gönderir. İhtiyacın olanı await et, sonra next() çağır.

next('route') ne yapar?

Mevcut route'un kalan handler'larını atlar ve eşleşen bir sonraki route'a geçer. Yalnızca app.get(), app.post() ve diğer metot fonksiyonlarıyla eklenen handler'larda çalışır, app.use() içinde çalışmaz.

Bir route için bir middleware'i nasıl atlarım?

O route'u middleware'den önce kaydet ki önce o cevap versin, ya da middleware'in içinde path'i kontrol et (if (req.path === '/health') return next();). Middleware'i tüm uygulama yerine router ya da route bazında uygulamak çoğu zaman bu ihtiyacı ortadan kaldırır.

Coddy programlama dilleri çizimi

Coddy ile kodlamayı öğren

Başla