Nuxt 3 mimarisinde middleware, bir rota geçişi gerçekleşmeden önce veya sonra yürütülen, asenkron işlevler olarak tanımlanır. Bu işlevler, modern web uygulamalarının kritik gereksinimlerinden olan kimlik doğrulama, yetkilendirme, veri doğrulama, loglama ve uluslararasılaştırma (i18n) gibi görevleri merkezi bir şekilde ele almayı sağlar. Nuxt 3'ün Vue 3 ve Nitro sunucusu üzerine inşa edilen hibrit yapısı, middleware'ların hem istemci tarafında (navigasyon koruyucu) hem de sunucu tarafında (API istek ön işleyicisi) etkin bir şekilde çalışabilmesine olanak tanır.
Temel olarak, middleware'lar yürütüldükleri bağlama göre üç ana tipte sınıflandırılabilir: route middleware, global (app) middleware ve server middleware. Route middleware, belirli sayfalar veya düzenler (layout) ile ilişkilendirilir ve yalnızca o rotalara erişim sırasında tetiklenir. Global middleware ise, uygulamanın her yeni rotası için otomatik olarak çalıştırılır, bu da onu kullanıcı oturumunun genel doğrulaması gibi evrnsel işlemler için ideal kılar. Server middleware kavramı, Nuxt'un Nitro sunucu motoru ile birlikte gelir ve API rotalarına gelen HTTP isteklerini işlemek için kullanılır, bu da onu geleneksel arka uç middleware'ına daha yakın bir yapı haline getirir.
| Middleware Türü | Yürütme Ortamı | Birincil Kullanım Amacı | Tanımlandığı Yer |
|---|---|---|---|
| Route Middleware | İstemci veya Sunucu Tarafı | Sayfa/Layout özel koruma ve ön işleme | /middleware dizini |
| Global Middleware | İstemci Tarafı | Tüm uygulama için geçerli iş mantığı | /middleware dizini (.global uzantılı) |
| Server Middleware | Sunucu Tarafı | API endpoint'leri için HTTP istek/yanıt işleme | /server/middleware dizini |
Bu tipler arasındaki temel fark, yürütme zamanı ve erişebildikleri bağlamdır. Route ve global middleware'lar, bir Vue bileşeni örneği oluşturulmadan önce, `setup()` fonksiyonu çağrılmadan yürütülür. Bu durum, bu middleware'ların, bileşenin henüz oluşturulmadığı bir aşamada çalıştığı anlamına gelir, dolayısıyla `this` anahtar kelimesine veya bileşen yaşam döngüsü kancalarına erişemezler. Bu, performans ve güvenlik açısından kritik bir tasarım tercihidir.
Route Middleware Uygulamaları
Route middleware'lar, Nuxt 3'teki en yaygın kullanılan middleware tipidir ve `/middleware` dizini altında tanımlanırlar. Her bir middleware dosyası, bir rota değişikliğini kontrol etmek ve yönlendirmek için kullanılabilecek bir asenkron işlev dışa aktarır. Bu işlev, iki temel argüman alır: mevcut rotaya ait bilgileri içeren `to` nesnesi ve çıkış yapılan rotayı temsil eden `from` nesnesi. İsteğe bağlı üçüncü bir `next` argümanı, Vue Router geleneğini takip eden eski bir yaklaşımdır; Nuxt 3'te doğrudan bir değer döndürme veya yönlendirme kullanımı teşvik edilir.
Middleware işlevi, bir değer döndürmezse, navigasyon otomatik olarak devam eder. Eğer `false` döndürürse, navigasyon iptal edilir ve mevcut sayfada kalınır. Bir `string` veya bir `route object` döndürürse, bu yeni hedefe yönlendirme yapılır. Bu mekanizma, yetkisiz erişim girişimlerini engellemek ve kullanıcıyı login sayfası gibi güvenli bir rotaya yönlendirmek için idealdir.
// middleware/auth.global.ts
export default defineNuxtRouteMiddleware((to, from) => {
const { status } = useAuth();
// `/login` rotasına erişimi koruma
if (to.path === '/login' && status.value === 'authenticated') {
return navigateTo('/dashboard');
}
// `/dashboard` gibi korumalı rotaları koruma
if (to.meta.requiresAuth && status.value === 'unauthenticated') {
// İptal et ve login sayfasına yönlendir
return abortNavigation("Erişim reddedildi.");
}
});
Bu kod örneğinde, `defineNuxtRouteMiddleware` yardımcı fonksiyonu kullanılarak tip güvenliği artırılmış bir yapı oluşturulmuştur. `useAuth` composable'ı, bir Pinia store'undan veya bir servisten alınan kimlik doğrulama durumunu sağlar. `navigateTo` ve `abortNavigation` Nuxt 3'in sağladığı yardımcı fonksiyonlardır; `navigateTo` sunucu tarafından (SSR) çağrıldığında uygun HTTP yönlendirme yanıtlarını (`3xx`) otomatik olarak ayarlayabilir.
| Döndürülen Değer / Aksiyon | Navigasyon Davranışı | Uygun Senaryo |
|---|---|---|
undefined / true |
Navigasyon devam eder. | Doğrulamanın başarılı olduğu durumlar. |
false |
Navigasyon sessizce iptal edilir. | Alternatif bir UI geri bildirimi sağlanacağı durumlar. |
navigateTo('/path') |
Belirtilen rotaya yönlendirilir. | Yetkisiz kullanıcıyı login sayfasına yönlendirme. |
abortNavigation(error?) |
Navigasyon hata ile iptal edilir. | Kritik yetkilendirme hatası, 404 sayfasına yönlendirme. |
Bir middleware'ı belirli bir sayfaya veya düzene bağlamak için, bileşen script bölümünde `definePageMeta` komutunu kullanmak gerekir. Bu komut, Nuxt 3'te sayfa meta verilerini tanımlamak için merkezi bir API sağlar. Bu yaklaşım, middleware'ların modüler ve yeniden kullanılabilir kalmasını sağlarken, her bir rotanın ihtiyaçlarını özelleştirmeye de olanak tanır. Örneğin, yalnızca yönetici paneli sayfalarını koruyan bir middleware, `definePageMeta({ middleware: 'admin-auth' })` şeklinde kolayca ilişkilendirilebilir. Bu şekilde, kod tekrarı en aza indirilir ve uygulama güvenlik politikaları tutarlı bir şekilde uygulanır.
Performans açısından, route middleware'larının içinde ağır senkron işlemlerden veya büyük veri setlerinin getirilmesinden kaçınılmalıdır. Ana işlevleri rotayı kontrol etmek ve yönlendirmek olmalıdır. Veri çekme işlemleri, `useAsyncData` veya `useFetch` composable'ları kullanılarak sayfa bileşenlerine bırakılmalıdır. Bu ayrım, uygulamanın yanıt verebilirliğini korur ve kullanıcı deneyimini olumsuz etkilemez. Middleware, bir kapı görevlisi gibi davranmalı, ev sahibi gibi değil.
Global ve Sunucu Middleware
Global middleware'lar, Nuxt uygulamasındaki her bir rota değişikliğinde otomatik olarak tetiklenen yapılardır. Tanımlanmaları için `/middleware` dizininde dosya adının sonuna `.global` eklenmesi yeterlidir (örneğin, `auth.global.ts`). Bu middleware tipi, kullanıcı oturumunun tüm uygulama genelinde sürekliliğini sağlamak, temel analitik verileri toplamak veya kullanıcının dil tercihini (`locale`) yönetmek gibi görevler için son derece uygundur. İstemci tarafında çalıştıkları için, `useRuntimeConfig` veya `useState` gibi Nuxt composable'larına doğrudan erişim sağlayabilirler, ancak sunucu tarafındaki Nitro bağlamına (`useRequestHeaders`, `useRequestEvent`) doğrudan erişimleri yoktur.
Global middleware'ların en önemli dezavantajı, uygulamanın ilk yükleme performansı üzerinde potansiyel etkileridir. Her rotada çalıştırıldıkları için, içlerindeki işlemlerin hafif ve hızlı olması kritik öneme sahiptir. Ağır bir global middleware, uygulamanın gezinme hızını önemli ölçüde düşürebilir. Bu nedenle, global middleware içindeki iş mantığı minimum düzeyde tutulmalı ve mümknse asenkron işlemlerden kaçınılmalıdır. Örneğin, bir token'ın varlığını kontrol etmek yeterliyken, her seferinde sunucuya bu token'ın geçerliliğini doğrulatan bir istekte bulunmamak gerekir. Bu doğrulama, sadece korumalı rotalara erişim sırasında yapılmalıdır.
Sunucu middleware'ları ise tamamen farklı bir bağlamda, Nuxt'un Nitro sunucusu üzerinde çalışır. `/server/middleware` dizini altında tanımlanırlar ve gelen HTTP isteklerini, herhangi bir API rotasına veya sunucu tarafı işleme ulaşmadan önce ele alırlar. Bu onları, gelen isteklerin loglanması, CORS başlıklarının eklenmesi, orijin doğrulaması, hız sınırlama (rate limiting) veya istek gövdelerinin (body) ön işlenmesi gibi senaryolar için ideal kılar. Sunucu middleware'ı, geleneksel Node.js framework'lerindeki (Express.js gibi) middleware kavramına oldukça benzerdir ve `defineEventHandler` içinde tanımlanır.
// server/middleware/security.ts
export default defineEventHandler((event) => {
// Tüm yanıtlara temel güvenlik başlıkları ekle
setResponseHeaders(event, {
'X-Content-Type-Options': 'nosniff',
'Referrer-Policy': 'strict-origin-when-cross-origin',
'X-Frame-Options': 'DENY'
});
// Basit bir orijin kontrolü (örneğin, belirli bir domain'den gelen istekleri sınırla)
const allowedOrigin = 'https://guvenlialanadim.com';
const requestOrigin = getRequestHeaders(event).origin;
if (requestOrigin && requestOrigin !== allowedOrigin) {
// İsteği reddet ve hata fırlat
throw createError({ statusCode: 403, statusMessage: 'Forbidden' });
}
// Middleware zincirine devam et (hiçbir şey döndürmemek devam etmeyi sağlar)
});
Bu kod parçası, sunucu middleware'ının güçlü yanını göstermektedir: HTTP istek/yanıt döngüsünün en alt katmanında işlem yapabilme yeteneği. `event` nesnesi, `h3` kütüphanesinin sağladığı tüm sunucu bağlamına erişim sağlar. Sunucu middleware'ları, yürütme sırasına göre bir zincir oluşturabilirler ve sıralama, dosya adlarına göre alfabetik olarak belirlenebilir. Bu sıralamanın dikkatli yapılması gerekir; örneğin bir loglama middleware'ı, CORS middleware'ından önce çalıştırılmalıdır ki tüm istekler kaydedilebilsin.
Global ve sunucu middleware'larının karşılaştırılması, Nuxt 3'ün full-stack yeteneklerini anlamak açısından önemlidir. Global middleware, istemci tarafı gezinme mantığına odaklanırken, sunucu middleware, HTTP protokolü seviyesinde güvenlik ve manipülasyon sağlar. Bu iki katmanın doğru kombinasyonu, sağlam ve güvenli uygulamaların temelidir. Örneğin, bir kullanıcının kimliği, sunucu middleware'ında bir JWT cookie'si ile doğrulanabilir ve ardından bu bilgi, global middleware aracılığıyla istemci tarafı durum yönetimi composable'larına enjekte edilebilir.
Middleware Best Practices
Nuxt 3 middleware'larının etkin ve güvenli bir şekilde kullanılması, uygulama mimarisinin bütünlüğü için hayati öneme sahiptir. İlk ve en önemli prensip, middleware'ların tek sorumluluk prensibine (Single Responsibility Principle) uygun olarak tasarlanmasıdır. Her bir middleware dosyası, belirli ve net bir görevi yerine getirmelidir. Örneğin, `auth.ts` yalnızca kimlik doğrulama kontrolü yaparken, `rate-limit.ts` yalnızca istek sınırlaması uygulamalıdır. Bu, kodun bakımını, test edilebilirliğini ve hata ayıklamasını büyük ölçüde kolaylaştırır. Büyük, monolitik bir middleware yerine, küçük ve odaklanmış middleware'ların zincirlenmesi (composition) tercih edilmelidir.
Hata yönetimi, middleware geliştirmede göz ardı edilmemesi gereken bir diğer kritik konudur. Middleware içinde oluşabilecek beklenmedik hatalar (örneğin, bir dış kimlik doğrulama servisine bağlanılamaması), `try...catch` blokları kullanılarak ele alınmalı ve kullanıcıya uygun bir geri bildirim sağlanmalıdır. Basitçe bir hata fırlatmak (`throw`), kullanıcıyı Nuxt'un genel hata sayfasına yönlendirebilir ki bu çoğu zaman istenmeyen bir durumdur. Bunun yerine, `abortNavigation` fonksiyonu ile açıklayıcı bir hata mesajı ile navigasyonu durdurmak veya `navigateTo('/error')` ile özel bir hata sayfasına yönlendirmek daha kullanıcı dostu bir yaklaşımdır.
Performans optimizasyonu bağlamında, middleware içindeki her türlü senkron olmayan işlem dikkatle değerlendirilmelidir. Özellikle sunucu middleware'larında, veritabanı sorguları veya dış API çağrıları yapılıyorsa, bu işlemlerin sonuçlarının uygun şekilde önbelleğe alınması (cache) veya gereksiz yere tekrarlanmaması için stratejiler geliştirilmelidir. Ayrıca, yalnızca mutlaka gerekli olan durumlarda global middleware kullanılmalıdır. Bir koruma mantığı sadece birkaç rota için gerekiyorsa, onu global yapmak yerine, route middleware olarak ilgili sayfalara `definePageMeta` ile eklemek daha verimlidir.
Güvenlik, middleware kullanımının merkezinde yer alır. Özellikle sunucu middleware'larında, gelen isteklerin doğrulanması ve sanitizasyonu (temizlenmesi) esastır. Kullanıcı girdilerine asla güvenilmemeli ve middleware katmanı, SQL enjeksiyonu, XSS (Cross-Site Scripting) veya CSRF (Cross-Site Request Forgery) gibi saldırılara karşı ilk savunma hattı olarak düşünülmelidir. Nuxt'un sağladığı `getQuery`, `readBody` gibi yardımcılar kullanılarak güvenli bir şekilde veri okunmalı, ardından Zod veya Joi gibi kütüphanelerle şema doğrulaması yapılmalıdır. Ayrıca, kimlik doğrulama token'larının veya oturum bilgilerinin istemci tarafında güvenli bir şekilde saklanması (örneğin, httpOnly cookie'ler) ve global/route middleware'larında bu bilgilere güvenli bir şekilde erişilmesi sağlanmalıdır.
| Antipattern / Hata | Potansiyel Sonuç | Önerilen Best Practice |
|---|---|---|
| Global middleware'da ağır API çağrıları | Tüm sayfa geçişlerinde gecikme, kötü kullanıcı deneyimi. | Hafif kontrolü global'de yap, ağır doğrulamayı korumalı rotanın kendisine veya sunucu middleware'ına bırak. |
| Middleware'da `throw new Error()` kullanmak | Kullanıcının genel hata sayfasına düşmesi, bağlam kaybı. | `abortNavigation(message)` veya `navigateTo('/custom-error')` kullan. |
| Tüm güvenlik kontrollerini istemci middleware'ına bırakmak | Güvenlik açıkları, kolayca atlatılabilir koruma. | Tüm kritik doğrulama ve yetkilendirmeyi sunucu middleware'ı ve API katmanında yap. |
| Middleware zincirinde sıralamayı (order) göz ardı etmek | Mantıksal hatalar, örneğin CORS'dan sonra loglama. | Sunucu middleware dosya isimlerini (`01.log.ts`, `02.cors.ts`) önekleyerek sırayı kontrol et. |
Sonuç olarak, Nuxt 3 middleware ekosistemi, full-stack uygulama geliştirmede güçlü bir soyutlama katmanı sunar. Ancak bu gücün sorumluluğu, geliştiricinin uygulayacağı disiplinli yaklaşımla doğru orantılıdır. Route, global ve sunucu middleware'larını uygun yerlerde, tek sorumluluk ilkesine uygun, hatalara karşı dayanıklı ve performans odaklı bir şekilde kullanmak, ölçeklenebilir ve güvenli Nuxt uygulamaları inşa etmenin anahtarıdır. Middleware, uygulama mantığınızın sessiz ve etkili düzenleyicisidir.
Test edilebilirlik de unutulmamalıdır. Middleware işlevleri, saf fonksiyonlara (pure functions) mümkün olduğunca yakın tasarlanmalıdır; yani, dış bağımlılıkları (dependency injection) parametre olarak almalı veya composable'lar aracılığıyla enjekte edilmelidir. Bu sayede, birim testleri (unit tests) yazmak ve farklı bağlamlarda (örneğin, farklı kullanıcı rolleri) middleware'ın davranışını simüle etmek çok daha kolay hale gelir. Nuxt 3'in geliştirme deneyimi, bu tür test stratejilerini uygulamak için gerekli araçları ve esnekliği sağlar.