[NODE JS] Express Route Parametreleri
id)
Route parametreleri dinamik URL segmentleridir. URL'nin bir bölümünü değişken olarak yakalamanızı sağlar. Mesela /users/5, /users/42, /users/ahmet gibi farklı URL'lerin hepsini tek bir route ile yakalayıp değişen kısmı parametre olarak okuyabilirsiniz. Bu web uygulamalarında en temel ihtiyaçlardan biridir.
Express'te route parametresi tanımlamak için path'te iki nokta
) kullanırsınız. /users/:id tanımında id bir parametredir ve req.params.id ile erişebilirsiniz. Birden fazla parametre de kullanabilirsiniz: /users/:userId/posts/
ostId gibi. Bu durumda req.params objesinde userId ve postId olarak iki parametre bulursunuz.Parametreler her zaman string olarak gelir. Yani req.params.id değeri "5" stringidir, 5 sayısı değil. Veritabanı sorgusunda kullanmadan önce parseInt veya Number ile sayıya çevirmeniz gerekir. Bu çok sık unutulan bir detay ve bazen çok sinsi bug'lara yol açar. Mesela loose equality (==) kullanıyorsanız sorun çıkmayabilir ama strict equality (===) kullanıyorsanız 5 === "5" false döner.
app.param() metodu belirli bir parametre her kullanıldığında otomatik çalışan bir middleware tanımlamanızı sağlar. Mesela her :id parametresi geldiğinde veritabanından kullanıcıyı çekip req objesine ekleme işlemini burada yapabilirsiniz. Bu DRY prensibine çok uygun bir yaklaşım çünkü aynı kontrol kodunu her route'ta tekrar yazmaktan kurtulursunuz.
Parametre validasyonu çok önemli bir konu. Kullanıcı URL'ye ne yazarsa yazsın sunucuya gelir. /users/abc, /users/-1, /users/0 gibi geçersiz değerler gelebilir. Bu yüzden parametreleri mutlaka validate etmeniz gerekiyor. Sayısal olması gereken parametreleri parseInt ile parse edip isNaN kontrolü yapın. String parametrelerde uzunluk ve karakter kontrolü yapın.
Ben bir keresinde parametre validasyonu yapmadığım için çok kötü bir bug yaşadım. MongoDB kullanıyorduk ve URL'den gelen id parametresini doğrudan sorguya veriyorduk. Birisi URL'ye geçersiz bir ObjectId yazdığında uygulama crash oluyordu. O günden sonra her parametreyi mutlaka validate ediyorum.
Opsiyonel parametreler de tanımlayabilirsiniz. Parametre adının sonuna soru işareti koyarak /:id? şeklinde opsiyonel hale getirebilirsiniz. Bu durumda /users ve /users/5 ikisi de aynı route'a düşer. Parametre verilmemişse req.params.id undefined olur.
Regex ile parametre kısıtlaması yapabilirsiniz. Express 4'te doğrudan route path'inde regex kullanamıyorsunuz ama app.param() içinde regex kontrolü yapabilirsiniz. Express 5'te bu özellik geliyor. Şu an için parametre geldiğinde handler içinde veya bir middleware'de kontrol etmek en yaygın yöntem.
Parametreleri hyphen (-) veya nokta (.) ile ayırarak daha karmaşık URL yapıları oluşturabilirsiniz. /flights/:from-:to veya /files/:name.:ext gibi. Bu özellikle dosya uzantılarını yakalamak veya tarih formatlarını parse etmek için kullanışlıdır. Express path'teki özel karakterleri tanır ve parametreleri doğru şekilde ayırır.
JavaScript:
const express = require('express');
const app = express();
app.use(express.json());
// Ornek veri seti
const kullanicilar = [
{{ id: 1, ad: 'Ahmet Yilmaz', yas: 28, sehir: 'Istanbul' }},
{{ id: 2, ad: 'Zeynep Kaya', yas: 34, sehir: 'Ankara' }},
{{ id: 3, ad: 'Mehmet Demir', yas: 25, sehir: 'Izmir' }},
{{ id: 4, ad: 'Fatma Celik', yas: 31, sehir: 'Bursa' }},
];
const siparisler = {{
1: [
{{ id: 101, urun: 'Laptop', tutar: 25000, tarih: '2024-01-15' }},
{{ id: 102, urun: 'Mouse', tutar: 800, tarih: '2024-02-20' }},
],
2: [
{{ id: 201, urun: 'Telefon', tutar: 18000, tarih: '2024-03-10' }},
],
3: [],
4: [
{{ id: 401, urun: 'Tablet', tutar: 12000, tarih: '2024-01-25' }},
{{ id: 402, urun: 'Kulaklik', tutar: 3500, tarih: '2024-04-05' }},
{{ id: 403, urun: 'Klavye', tutar: 2200, tarih: '2024-04-15' }},
],
}};
// ===== app.param() ile parametre middleware =====
// :kullaniciId parametresi her kullanildiginda calisir
app.param('kullaniciId', (req, res, next, id) => {{
const numId = parseInt(id, 10);
if (isNaN(numId) || numId <= 0) {{
return res.status(400).json({{
hata: 'Gecersiz kullanici ID',
detay: 'ID pozitif bir sayi olmalidir',
}});
}}
const kullanici = kullanicilar.find(k => k.id === numId);
if (!kullanici) {{
return res.status(404).json({{ hata: `Kullanici ${{numId}} bulunamadi` }});
}}
req.kullanici = kullanici;
next();
}});
// Artik her route'ta kullanici kontrolu yapmamiza gerek yok
app.get('/api/kullanicilar/:kullaniciId', (req, res) => {{
res.json(req.kullanici);
}});
app.put('/api/kullanicilar/:kullaniciId', (req, res) => {{
Object.assign(req.kullanici, req.body);
res.json({{ mesaj: 'Kullanici guncellendi', kullanici: req.kullanici }});
}});
app.delete('/api/kullanicilar/:kullaniciId', (req, res) => {{
const index = kullanicilar.findIndex(k => k.id === req.kullanici.id);
kullanicilar.splice(index, 1);
res.json({{ mesaj: 'Kullanici silindi' }});
}});
// ===== IC ICE PARAMETRELER =====
// /api/kullanicilar/1/siparisler
app.get('/api/kullanicilar/:kullaniciId/siparisler', (req, res) => {{
const kullaniciSiparisleri = siparisler[req.kullanici.id] || [];
res.json({{
kullanici: req.kullanici.ad,
siparisler: kullaniciSiparisleri,
toplam: kullaniciSiparisleri.length,
}});
}});
// /api/kullanicilar/1/siparisler/101
app.get('/api/kullanicilar/:kullaniciId/siparisler/:siparisId', (req, res) => {{
const siparisId = parseInt(req.params.siparisId, 10);
const kullaniciSiparisleri = siparisler[req.kullanici.id] || [];
const siparis = kullaniciSiparisleri.find(s => s.id === siparisId);
if (!siparis) {{
return res.status(404).json({{ hata: 'Siparis bulunamadi' }});
}}
res.json({{ kullanici: req.kullanici.ad, siparis }});
}});
// ===== OZEL AYIRICILI PARAMETRELER =====
// Tarih parametresi: /api/etkinlikler/2024-01-15
app.get('/api/etkinlikler/:yil-:ay-:gun', (req, res) => {{
const {{ yil, ay, gun }} = req.params;
res.json({{
tarih: `${{gun}}/${{ay}}/${{yil}}`,
yil: parseInt(yil),
ay: parseInt(ay),
gun: parseInt(gun),
}});
}});
// Dosya uzantisi yakalama: /api/dosyalar/rapor.pdf
app.get('/api/dosyalar/:isim.:uzanti', (req, res) => {{
res.json({{
dosyaAdi: req.params.isim,
uzanti: req.params.uzanti,
tamAd: `${{req.params.isim}}.${{req.params.uzanti}}`,
}});
}});
// Ucus rotasi: /api/ucuslar/IST-ADB
app.get('/api/ucuslar/:kalkis-:varis', (req, res) => {{
res.json({{
kalkis: req.params.kalkis,
varis: req.params.varis,
rota: `${{req.params.kalkis}} -> ${{req.params.varis}}`,
}});
}});
// Tum kullanicilari listele (parametre yok)
app.get('/api/kullanicilar', (req, res) => {{
res.json({{ toplam: kullanicilar.length, kullanicilar }});
}});
app.listen(3000, () => {{
console.log('Route parametreleri sunucusu port 3000\'de');
}});
Parametreleri kullanırken SQL injection ve NoSQL injection saldırılarına dikkat edin. Parametreleri doğrudan veritabanı sorgusuna yerleştirmek yerine prepared statements veya ORM kullanın. Güvenlik her zaman birinci önceliğiniz olmalı.
Emeğiniz ve katkınız için teşekkür ederiz!
Konunuz gerekli incelemelerden geçerek onaylandı. Topluluğumuza katkılarınızın devamını bekliyoruz.
İyi forumlar!
Konunuz gerekli incelemelerden geçerek onaylandı. Topluluğumuza katkılarınızın devamını bekliyoruz.
İyi forumlar!
