Express'te routing bir HTTP metodunu ve bir path'i bir handler fonksiyonuyla eşleştirir: app.get('/users', handler) /users adresine gelen GET isteklerine cevap verir, app.post(), app.put() ve app.delete() da diğer metotlar için aynısını yapar. /users/:id örneğindeki gibi iki nokta ile başlayan bir parça bir route parametresidir ve değeri req.params içine düşer. Büyüyen bir uygulamayı düzenli tutmak için ilgili route'ları bir express.Router() içine koy ve onu app.use('/api', router) ile bir önek altına bağla.
GET /users/2, {"id":2,"name":"Linus"} ile cevap verir. Route parametreleri her zaman string'dir, handler'ın Number(req.params.id) ile karşılaştırmasının nedeni bu. 201 almak için {"name": "Grace"} body'siyle POST /users gönder, sonra listenin değiştiğini görmek için DELETE /users/1 ve GET /users gönder.
Önekli express.Router()
Router, kendi route'ları ve middleware'i olan küçük bir uygulamadır. Path'leri görecelidir: /api/books altına bağlanmış bir router içinde /:id olarak yazılan bir route /api/books/:id adresine cevap verir. Gerçek bir projede her router kendi dosyasında durur ve module.exports = router ile biter.
GET /api/books/1, {"id":1,"title":"Dune"} döndürür. router.route('/:id') path'i bir kez yazar ve her metot için bir handler zincirler; PUT /api/books/1 gönderirsen {"updated":"1"} alırsın. Bağlama path'ini /v2/books yap, aynı router bu sefer orada cevap verir.
Route sırası: ilk eşleşme kazanır
Express route'ları kaydettiğin sırayla dener ve response gönderen ilk route'ta durur. Parametreli bir route kendi konumundaki her şeyi yakalar, bu yüzden ondan sonra kaydedilen sabit bir path'e hiç ulaşılmaz:
GET /users/new, {"route":"/users/:id","id":"new"} ile cevap verir: parametreli route önce kaydedildi ve isteği o aldı. /users/new route'unu /users/:id route'unun üstüne taşı ve {"route":"/users/new"} almak için tekrar çalıştır. Sonra en alttaki 404 handler'ına ulaşmak için GET /books gönder.
404 handler'ı
Express eşleşmeyen bir isteğe kendi HTML sayfasıyla, Cannot GET /books ile cevap verir. Bir API için genelde JSON istersin, bu yüzden yukarıdaki örnekte olduğu gibi en son route olarak path'siz bir app.use() ekle. Yalnızca önündeki her route isteği ilettiğinde çalışır. Handler'ların fırlattığı hatalar ise kendi dört argümanlı handler'ı olan farklı bir durumdur, onu Express error handling anlatıyor.
Express 5'te route path'leri
Express 5 path sözdizimini değiştirdi ve internetteki örneklerin çoğu Express 4 için yazılmış:
| Kalıp | Express 4 | Express 5 |
|---|---|---|
| Herhangi bir path | app.get('*', fn) | app.get('/*splat', fn) |
| Opsiyonel parametre | /users/:id? | /users{/:id} |
| Parametre üzerinde kalıp | /users/:id(\\d+) | Desteklenmiyor; değeri handler'da kontrol et |
Tek başına bir * ya da bir parametreden sonra ?, route kaydedilirken bir TypeError fırlatır, bu yüzden uygulama başlamaz.
Sık yapılan hatalar
404 handler'ını en başa kaydetmek. Path'siz app.use() her şeyle eşleşir, bu yüzden her istek 404 alır. Onu en altta tut.
Önekin silindiğini unutmak. /api altına bağlanmış bir router içinde req.path, /api içermez. Tam path'e ihtiyacın olduğunda req.originalUrl kullan.
Bir parametreyi bir sayıyla karşılaştırmak. req.params.id === 1 her zaman false'tur, çünkü req.params.id '1' string'idir.
Sıkça Sorulan Sorular
app.use ile app.get arasındaki fark nedir?
app.get('/users', fn), fn fonksiyonunu yalnızca path'i tam olarak /users olan GET istekleri için çalıştırır. app.use('/users', fn) ise her metot için ve /users ile başlayan her path için çalışır; router ve middleware bağlamak için kullanılmasının nedeni budur.
Express route'larını büyük küçük harfe duyarlı nasıl yaparım?
Route'lar varsayılan olarak büyük küçük harfe bakmaz, yani /Users, /users ile eşleşir. Bunu app.set('case sensitive routing', true) ile ya da router bazında express.Router({ caseSensitive: true }) ile kapat.
İç içe bir router'da req.params neden boş?
Bir router yalnızca kendi path'lerinin parametrelerini görür. /users/:userId/posts altına bağlanmışsa, üst path'teki req.params.userId değerine erişebilmek için onu express.Router({ mergeParams: true }) ile oluştur.
Her route'u tek bir dosyaya mı koymalıyım?
Bir avuçtan fazla route'un olduğunda hayır. Her kaynak için bir router oluştur (routes/users.js, routes/orders.js), onu module.exports = router ile export et ve her birini ana dosyada app.use() ile bağla.