Kural
İstenmeyen global değişken önbelleklemesinden kaçının. Node.js
ve Python sunucularında global değişkenler istekler boyunca
kalıcılığını korur; bu da veri sızıntılarına ve race condition'lara yol açar.
Desteklenen diller: JavaScript, TypeScript, PythonGiriş
Node.js sunucularındaki global değişkenler, yalnızca tek bir isteklik süre boyunca değil, sürecin (process) yaşam döngüsü boyunca kalır. İstek işleyicileri (request handlers) kullanıcı verilerini global değişkenlerde sakladığında, bu verilere farklı kullanıcılardan gelen sonraki istekler üzerinden de erişilebilir. Bu durum, A kullanıcısının oturum verilerinin, kimlik doğrulama token'larının veya kişisel bilgilerinin B kullanıcısına sızdığı güvenlik açıklarına yol açar.
Neden önemli?
Güvenlik etkileri (veri sızıntıları): Kullanıcıya özel verileri önbelleğe alan global değişkenler, istekler arası veri sızıntılarına neden olur. Bir kullanıcının kimlik doğrulama durumu, oturum verileri veya kişisel bilgileri diğer kullanıcılar tarafından görülebilir hale gelir; bu da gizlilik ve güvenlik sınırlarını ihlal eder.
Race condition'lar: Birden fazla eşzamanlı (concurrent) istek aynı global değişkeni değiştirdiğinde, öngörülemeyen davranışların ortaya çıkma olasılığı yüksek olur. A kullanıcısının verileri, işlem devam ederken B kullanıcısının isteği tarafından üzerine yazılarak silinebilir; bu da yanlış hesaplamalara, bozulmuş durumlara (corrupted state) veya kullanıcıların birbirlerinin verilerini görmesine yol açabilir.
Hata ayıklama karmaşıklığı (Debugging complexity): Global değişken önbelleklemesinden kaynaklanan sorunların yeniden üretilmesi (reproduce) son derece zordur çünkü bunlar isteğin zamanlamasına ve eşzamanlılığa bağlıdır. Hatalar, yük altında üretim ortamında (production) aralıklı olarak ortaya çıkar ancak tek iş parçacıklı (single-threaded) geliştirme testlerinde nadiren kendini gösterir.
Bellek sızıntıları: Temizleme yapılmadan veri biriktiren genel (global) değişkenler zamanla sınırsız şekilde büyür. Her istek, genel önbelleklere veya dizilere daha fazla veri ekler; bu da sonunda sunucu belleğini tükatarak süreçlerin (process) yeniden başlatılmasını gerektirir.
Kod örnekleri
❌ Kural dışı:
let currentUser = null;
let requestData = {};
app.get('/profile', async (req, res) => {
currentUser = await getUserById(req.userId);
requestData = req.body;
const profile = await buildUserProfile(currentUser);
res.json(profile);
});
function buildUserProfile(user) {
return {
name: currentUser.name,
data: requestData
};
}
Neden yanlış: currentUser ve requestData genel değişkenleri istekler boyunca kalıcılığını korur. Birden fazla istek eşzamanlı olarak yürütüldüğünde, kullanıcı A'nın buildUserProfile() işlevi hâlâ çalışırken kullanıcı B'nin isteği currentUser değişkeninin üzerine yazabilir ve kullanıcı A'nın, kullanıcı B'nin verilerini görmesine neden olabilir.
✅ Kurallara uygun:
app.get('/profile', async (req, res) => {
const currentUser = await getUserById(req.userId);
const requestData = req.body;
const profile = buildUserProfile(currentUser, requestData);
res.json(profile);
});
function buildUserProfile(user, data) {
return {
name: user.name,
data: data
};
}
Bu neden önemli: İstekle ilgili tüm veriler, istek işleyicisinin (request handler) kapsamındaki yerel değişkenlerde saklanır. Her isteğin, diğer eşzamanlı isteklere sızamayacak izole bir durumu vardır. İşlevler, genel duruma erişmek yerine verileri parametreler aracılığıyla alır; böylece yarış durumları (race conditions) ortadan kalkar.
Sonuç
İstekle ilgili tüm verileri yerel değişkenlerde veya çerçeveniz (framework) tarafından sağlanan istek nesnelerinde tutun. Genel değişkenleri yalnızca yapılandırma, bağlantı havuzları veya salt okunur önbellekler gibi gerçekten paylaşılan durumlar için kullanın. Genel durum gerekli olduğunda, uygun eşzamanlılık kontrolleri kullanın ve verilerin hiçbir zaman kullanıcıya özel olmadığından emin olun.

