Express alapok · 4. tananyag
Egy webshop API-nak tucatnyi végpontja van, és ezek nagy része nem fix cím, hanem minta:
a /api/products/42 és a
/api/products/1337 ugyanaz a
végpont. Ez a fejezet arról szól, hogyan válogatja szét az Express a kéréseket.
:id) használni, és tudni, hogy az értéke
mindig szöveg;?page=2) olvasni, kezelni a hiányzó és a
többszörös értékeket;/*splat,
{/:id} — és felismerni a régi szintaxis hibaüzeneteit;express.Router() segítségével külön fájlokba szervezni a
végpontokat;app.route(), az app.all()
és a több kezelőfüggvény.Az útvonalminták szintaxisa az Express 5-ben megváltozott. A neten talált példák jó része itt már hibát dob — ezért a 6. szakaszban külön végigmegyünk rajta.
Egy útvonal (route) három részből áll:
Az Express minden beérkező kérésnél végigmegy a regisztrált útvonalakon, és megkeresi az elsőt, amelyiknél a metódus is és az útvonal is illeszkedik. Ha talál ilyet, meghívja a kezelőfüggvényt. Ha nem talál, a beépített 404-es válasz megy vissza.
A metódus és az erőforrás együtt írja le a szándékot:
GET /api/products = „add ide a termékeket”,
DELETE /api/products/42 = „töröld a 42-est”. Ugyanaz az útvonal más
metódussal más művelet.
| Metódus | Express-hívás | Mire használjuk a webshopban? |
|---|---|---|
GET | app.get(minta, fv) | Lekérdezés: terméklista, egy termék |
POST | app.post(minta, fv) | Létrehozás: új termék, új rendelés |
PUT | app.put(minta, fv) | Teljes felülírás: a termék minden mezője |
PATCH | app.patch(minta, fv) | Részleges módosítás: csak az ár |
DELETE | app.delete(minta, fv) | Törlés |
app.delete ÉS NEM app.del?
Mert a delete a JavaScriptben ugyan kulcsszó, de metódusnévként
használható (app.delete(...)) — csak önálló változónévként nem lenne az. Régi
példákban néha app.del szerepel: ez már nem létezik.
A webshop végponttérképe így néz ki:
app.get("/api/products", …); // összes termék app.get("/api/products/:id", …); // egy termék app.post("/api/products", …); // új termék app.put("/api/products/:id", …); // teljes felülírás app.patch("/api/products/:id", …); // részleges módosítás app.delete("/api/products/:id", …); // törlés
Figyeld meg: kétféle útvonalminta van összesen (/api/products és
/api/products/:id), de hat végpont — mert a metódus is a végpont része.
Az Express fentről lefelé haladva keresi az első illeszkedő útvonalat, és megáll az elsőnél. Ez a legtöbb kezdő hiba forrása.
Nézd meg ezt a kódot, és tippelj: mit ad vissza a GET /api/products/uj kérés?
app.get("/api/products/:id", (req, res) => { res.json({ talalat: "egy termék", id: req.params.id }); }); app.get("/api/products/uj", (req, res) => { res.json({ talalat: "űrlap új termékhez" }); });
Kipróbálva (Express 5.2.1):
GET /api/products/uj → 200 {"talalat":"egy termék","id":"uj"}
A második útvonal soha nem fut le. A :id minta ugyanis az
uj szóra is illeszkedik — a paraméter értéke egyszerűen
"uj" lesz. Nincs hibaüzenet, nincs figyelmeztetés: a végpont
csendben halott.
A megoldás: a konkrét minta kerüljön a rugalmas elé.
app.get("/api/products/uj", …); // ✅ előbb a konkrét app.get("/api/products/:id", …); // ✅ utána a paraméteres
Ha két útvonalminta ugyanarra a címre illeszkedhet, mindig a szűkebb kerül előre. A gyakorlatban: fix szövegek előbb, paraméteres minták utánuk, a mindent elkapó minták (404-kezelő) legvégül.
A metódus is része az illeszkedésnek, ezért ez a két sor nem ütközik:
app.get("/api/products/:id", …); // lekérdezés app.delete("/api/products/:id", …); // törlés
Ugyanaz a minta, más metódus — más végpont.
Adott egy útvonallista abban a sorrendben, ahogy a kódban szerepel, és egy beérkező kérés. Válaszd ki, melyik kezelőfüggvény fut le! Figyelj a metódusra és a sorrendre is.
:idA kettősponttal kezdődő szakasz paraméter: bármire illeszkedik, ami nem tartalmaz
perjelet, és az értéke a req.params objektumba kerül.
app.get("/api/products/:id", (req, res) => { console.log(req.params); // { id: "42" } res.json({ kert: req.params.id }); });
| Kérés | req.params |
|---|---|
GET /api/products/42 | { id: "42" } |
GET /api/products/uj | { id: "uj" } |
GET /api/products/abc-123 | { id: "abc-123" } |
app.get("/api/categories/:catId/products/:prodId", (req, res) => { res.json(req.params); });
GET /api/categories/3/products/9 → {"catId":"3","prodId":"9"}
A paraméter nevét te választod meg — a req.params kulcsai ezek a
nevek lesznek. Írd őket beszédesen: :id egyértelmű, ha csak egy van, de két
azonosítónál :catId és :prodId sokkal olvashatóbb.
Ez a fejezet legfontosabb buktatója:
app.get("/api/products/:id", (req, res) => { const id = req.params.id; // "42" — SZÖVEG! const termek = termekek.find(t => t.id === id); // ❌ soha nem talál semmit });
A tömbben az id szám (42), a
paraméterben szöveg ("42"), és a
=== a típust is nézi: "42" === 42 →
false.
A helyes megoldás:
app.get("/api/products/:id", (req, res) => { const id = Number(req.params.id); if (Number.isNaN(id)) { return res.status(400).json({ error: { message: "Az azonosító csak szám lehet." } }); } const termek = termekek.find(t => t.id === id); if (!termek) { return res.status(404).json({ error: { message: "Nincs ilyen termék." } }); } res.json(termek); });
| Lépés | Miért kell? |
|---|---|
Number(...) | Mert a req.params értéke szöveg, az adataink azonosítója viszont szám |
Number.isNaN(id) ellenőrzés | Mert a /api/products/alma is illeszkedik a mintára — a Number("alma") pedig NaN |
400 a rossz formátumra | A kérés hibás volt, nem az erőforrás hiányzik |
404 a nem létező termékre | A kérés rendben volt, csak nincs ilyen elem |
return a válasz előtt | Hogy a függvény ne fusson tovább — lásd az előző fejezetet |
Number() ÉS NEM parseInt()?
A parseInt("42abc") eredménye 42 — vagyis elfogadna
hibás azonosítót is. A Number("42abc") viszont NaN,
tehát elbukik a vizsgálaton. Szigorúbb, és itt épp ezt akarjuk.
?page=2Amíg az útvonalparaméter azt mondja meg, melyik erőforrásról van szó, a query string azt, hogy hogyan kérjük: szűrés, rendezés, lapozás.
app.get("/api/products", (req, res) => { console.log(req.query); res.json(termekek); });
GET /api/products?page=2&limit=10 → req.query = { page: "2", limit: "10" }
| Eset | Kérés | req.query értéke |
|---|---|---|
| Egyszerű érték | ?page=2 | { page: "2" } — szöveg |
| Hiányzó paraméter | ? (semmi) | {} — a req.query.page undefined |
| Érték nélküli kulcs | ?akcio | { akcio: "" } — üres szöveg, nem true! |
| Ugyanaz a kulcs többször | ?b=x&b=y | { b: ["x", "y"] } — tömb! |
Ez a négy sor mind valódi, kipróbált eredmény Express 5.2.1-en. A harmadik és a negyedik sor az, ami meglepetést szokott okozni.
Mivel minden szövegként érkezik, és bármelyik hiányozhat, a gyakorlatban így dolgozunk vele:
app.get("/api/products", (req, res) => { const oldal = Number(req.query.page) || 1; // hiányzik vagy nem szám → 1 const meret = Number(req.query.limit) || 20; // hiányzik vagy nem szám → 20 const kereses = req.query.q ?? ""; // hiányzik → üres szöveg // …szűrés és lapozás… });
| Írásmód | Mit csinál? | Mikor használd? |
|---|---|---|
Number(x) || alapertek | Ha az eredmény NaN vagy 0, az alapértéket adja | Számoknál, ahol a 0 úgysem érvényes (oldalszám, elemszám) |
x ?? alapertek | Csak akkor ad alapértéket, ha x értéke null vagy undefined | Szövegeknél, ahol az üres szöveg érvényes érték lehet |
|| OPERÁTORRAL!
A Number("0") || 20 eredménye 20, mert a
0 hamis értéknek számít. Oldalszámnál ez nem gond (nincs 0. oldal), de ha egy
paraméternél a 0 érvényes érték, akkor a
?? a helyes választás.
Mivel a ?akcio üres szöveget ad, logikai kapcsolót így vizsgálunk:
const csakAkcios = req.query.akcio === "true" || req.query.akcio === "";
Vagy — tisztább, ha megköveteljük az értéket (?akcio=true):
const csakAkcios = req.query.akcio === "true";
Az API dokumentációjában rögzítsd, hogy ?akcio=true alakot vársz. Ez pontosan az
a „szerződés”, amiről az 1. blokk 2. fejezetében volt szó.
req.params vs. req.query — mikor melyik?req.params | req.query | |
|---|---|---|
| Honnan jön? | Az útvonalból: /products/42 | A query stringből: ?page=2 |
| Mit fejez ki? | Melyik erőforrás | Hogyan kérem (szűrés, lapozás, rendezés) |
| Kötelező? | Igen — enélkül nem illeszkedik az útvonal | Nem — mindig lehet hiányzó |
| Típusa | Mindig szöveg | Szöveg vagy szövegtömb |
Ökölszabály: ha az adat nélkül a végpontnak nincs értelme, útvonalparaméter. Ha csak finomítja az eredményt, query paraméter.
GET /api/products/42 ✅ a 42 nélkül nincs mit visszaadni → útvonalparaméter GET /api/products?categoryId=3 ✅ nélküle is van válasz (minden termék) → query GET /api/products/42?mezok=nev ✅ a kettő egyszerre is használható
Hat adat a webshop API-ból. Döntsd el mindegyikről, hogy az útvonalba vagy a query stringbe való — ez az API tervezésének egyik alapdöntése.
Itt tér el leglátványosabban az Express 5 a 4-estől. A minták feldolgozását végző könyvtár
(path-to-regexp) nagyot változott, és több régi írásmód
hibát dob indításkor.
| Régi (Express 4) írásmód | Mit jelentett? | Express 5-ben |
|---|---|---|
app.get("*", …) | minden útvonal | PathError |
app.get("/files/*", …) | minden a /files/ alatt | PathError |
app.get("/users/:id?", …) | opcionális paraméter | PathError |
app.get("/:id(\d+)", …) | csak számokra illeszkedő paraméter | PathError |
app.get("/ab+cd", …) | ismétlődő betű | PathError |
A hibaüzenetek (valódi, kipróbált kimenet):
PathError [TypeError]: Missing parameter name at index 1: *; visit https://git.new/pathToRegexpError for info
PathError [TypeError]: Unexpected ? at index 10: /users/:id?; visit https://git.new/pathToRegexpError for info
PathError [TypeError]: Unexpected ( at index 4: /:id(\d+); visit https://git.new/pathToRegexpError for info
A szerver el sem indul, nem pedig futás közben romlik el. Ha ezt látod, egyetlen sort kell
átírnod — a hibaüzenet meg is mondja, hányadik karakternél akadt el, és hogy melyik mintát
írtad. A PathError [TypeError] írásmód azt jelenti, hogy a hiba saját neve
PathError, a típusa pedig TypeError — a Node így
írja ki a kettőt együtt.
| Feladat | Express 5-ös írásmód | Megjegyzés |
|---|---|---|
| Minden útvonal | app.use((req, res) => …) | Mintát meg sem adunk — a 404-kezelő így készül |
Minden a /files/ alatt | app.get("/files/*splat", …) | A * után nevet kell adni |
| Opcionális szakasz | app.get("/users{/:id}", …) | A kapcsos zárójel opcionális részt jelöl |
| Csak számokra illeszkedő | Nincs mintában — a kezelőben ellenőrizzük | Ahogy a 3. szakaszban láttuk |
*splat)app.get("/files/*splat", (req, res) => { res.json({ params: req.params }); });
Kipróbálva:
GET /files/kepek/2026/logo.png
→ {"params":{"splat":["kepek","2026","logo.png"]}}
splat ÉRTÉKE TÖMB, NEM SZÖVEG!
A szakaszokra bontott útvonalat kapod meg. Ha egyben kell, fűzd össze:
req.params.splat.
A splat név nem kötelező, csak szokás — /*utvonal
esetén a kulcs utvonal lesz.
{…})app.get("/users{/:id}", (req, res) => { res.json({ params: req.params }); });
GET /users → {"params":{}} — a req.params.id itt undefined
GET /users/7 → {"params":{"id":"7"}}
Figyeld meg, hogy a perjel is a kapcsos zárójelen belül van:
{/:id}, nem /{:id}. Így a
/users (perjel nélkül) is illeszkedik.
A gyakorlatban ritkán. Sokkal olvashatóbb két külön útvonal:
app.get("/users", …) a listához és
app.get("/users/:id", …) az egyeshez — más is a válaszuk (tömb vs. objektum).
Az opcionális szakaszt akkor érdemes bevetni, ha a két eset tényleg ugyanaz a művelet.
app.get(["/api/products", "/api/termekek"], …); // ✅ több minta tömbben app.get(/^\/x\d+$/, …); // ✅ reguláris kifejezés
Reguláris kifejezést csak akkor használj, ha tényleg nincs más — nehezen olvasható, és a paraméterek nevesítése is körülményes.
Az Express alapból elnéző:
| Kérés | Regisztrált útvonal | Illeszkedik? |
|---|---|---|
GET /termek | app.get("/Termek", …) | ✅ igen — nem érzékeny a kis- és nagybetűre |
GET /valami/ | app.get("/valami", …) | ✅ igen — a záró perjel nem számít |
Mindkét viselkedés átállítható
(app.set("case sensitive routing", true),
app.set("strict routing", true)), de az alapbeállítás a barátságosabb —
hagyd békén.
express.Router() — végpontok külön fájlbaEddig minden útvonal az app.js-ben volt. Egy valódi API-nál ez néhány száz sor
után áttekinthetetlen — ráadásul minden útvonal elején ott az ismétlődő
/api/products előtag.
A Router egy önálló, mini alkalmazás: ugyanúgy vesz fel
útvonalakat, de nem indít szervert. Kész állapotban „felakasztjuk” az alkalmazásra egy előtag alá.
routes/products.jsRELATÍVimport express from "express"; const router = express.Router(); router.get("/", (req, res) => { res.json(termekek); }); router.get("/:id", (req, res) => { res.json({ id: Number(req.params.id) }); }); router.post("/", (req, res) => { res.status(201).json({ letrehozva: true }); }); export default router;
app.jsAZ ELŐTAGimport express from "express"; import termekRouter from "./routes/products.js"; const app = express(); app.use(express.json()); // ide akasztjuk fel: app.use("/api/products", termekRouter); export default app;
| Elem | Mit csinál? |
|---|---|
express.Router() | Létrehoz egy üres, önálló útvonalgyűjteményt |
router.get("/", …) | A router saját gyökeréhez képest értelmezi az útvonalat |
app.use(elotag, router) | „Felakasztja” a routert: minden benne lévő útvonal elé kerül az előtag |
| Előny | Magyarázat |
|---|---|
| Egy fájl, egy erőforrás | A routes/products.js csak a termékekkel foglalkozik |
| Az előtag egy helyen van | Ha /api/products-ból /api/v2/products lesz, egyetlen sort írsz át |
| Rövidebb minták | "/" és "/:id" a hosszú teljes útvonalak helyett |
| Újrafelhasználható | Ugyanaz a router több előtag alá is felakasztható |
webshop-api/ app.js ← az alkalmazás felépítése, a routerek felakasztása index.js ← a szerver indítása routes/ products.js ← /api/products végpontjai categories.js ← /api/categories végpontjai orders.js ← /api/orders végpontjai
Ez a szerkezet a 7. fejezetben bővül tovább (controller- és service-réteggel) — most elég annyi, hogy a végpontok erőforrásonként külön fájlba kerülnek.
router.get("/", (req, res) => { res.json({ baseUrl: req.baseUrl, url: req.url, originalUrl: req.originalUrl }); });
GET /api/orders esetén az eredmény:
{ "baseUrl": "/api/orders", "url": "/", "originalUrl": "/api/orders" }
| Tulajdonság | Mit tartalmaz? |
|---|---|
req.baseUrl | Az előtag, ami alá a routert akasztottuk: /api/orders |
req.url | A routeren belüli útvonal: / |
req.originalUrl | A kliens által kért teljes útvonal: /api/orders |
Naplózáshoz szinte mindig az originalUrl kell — az
url a routerben félrevezető lenne.
mergeParamsHa a routert paraméteres előtag alá akasztod, a paraméter alapból nem látszik a belső
routerben. Ezért kell a mergeParams:
const tetelekRouter = express.Router({ mergeParams: true }); tetelekRouter.get("/", (req, res) => { res.json(req.params); // { shopId: "12" } }); const boltRouter = express.Router(); boltRouter.use("/:shopId/items", tetelekRouter); app.use("/shops", boltRouter);
GET /shops/12/items → {"shopId":"12"}
mergeParams: true nélkül a req.params
üres objektum lenne. Ez ritkábban kell, de amikor igen, órákat lehet vele elveszíteni.
app.route() — ugyanaz az útvonal, több metódusapp.route("/api/products/:id") .get((req, res) => res.json({ muvelet: "lekérés" })) .put((req, res) => res.json({ muvelet: "felülírás" })) .delete((req, res) => res.sendStatus(204));
Az útvonalminta egyszer szerepel — kevesebb az elgépelés esélye. A működés azonos azzal,
mintha három külön app.get / app.put /
app.delete hívást írnál.
Amit nem regisztráltál, arra 404 jön: a fenti kódnál a
PATCH /api/products/42 kérésre 404-et kapsz.
app.all() — minden metódusapp.all("/mind", (req, res) => { res.json({ metodus: req.method }); });
GET /mind → {"metodus":"GET"}
POST /mind → {"metodus":"POST"}
DELETE /mind → {"metodus":"DELETE"}
Ritkán kell — jellemzően közös előfeldolgozásra (naplózás, hitelesítés-ellenőrzés) egy adott útvonalon. Erre viszont a 6. fejezetben tanult middleware általában jobb eszköz.
Az 1. blokk 2. fejezetében volt szó a HEAD és az
OPTIONS metódusról. Az Express ezeket automatikusan kezeli a
regisztrált útvonalaid alapján:
OPTIONS /api/lanc → 200, Allow: GET, HEAD, POST
Ez is kipróbált eredmény: a .get() és .post()
regisztrációból az Express kitalálta, mit írjon az Allow fejlécbe — és a
HEAD-et magától hozzátette a GET mellé.
Egy útvonalhoz több függvényt is megadhatsz, vesszővel elválasztva:
function bejelentkezveKell(req, res, next) { // …ellenőrzés… next(); // ← továbbadjuk a következőnek } app.delete("/api/products/:id", bejelentkezveKell, (req, res) => { res.sendStatus(204); });
A next() hívás adja tovább a vezérlést a láncban következő függvénynek.
Ez már middleware — a 6. fejezet erről szól részletesen. Itt csak annyit jegyezz meg, hogy
az útvonal kezelőfüggvénye nem feltétlenül egyetlen függvény.
app.get("/api/products/:id", …); app.get("/api/products/uj", …); // ❌ soha nem fut le
Tünet: a /api/products/uj a :id
ágra fut, id: "uj" értékkel.
Megoldás: a konkrét minta a paraméteres elé.
const termek = termekek.find(t => t.id === req.params.id); // ❌ "42" === 42
Tünet: mindig 404, pedig a termék létezik.
Megoldás: Number(req.params.id).
app.get("*", (req, res) => res.status(404).json({ error: "Nincs ilyen végpont." }));
Tünet: a szerver el sem indul:
PathError [TypeError]: Missing parameter name at index 1: *; visit https://git.new/pathToRegexpError for info
Megoldás: mintát meg sem adunk, csak app.use()-t használunk a
lánc végén:
app.use((req, res) => { res.status(404).json({ error: { message: "Nincs ilyen végpont." } }); });
Erről a 8. fejezetben (hibakezelés) lesz szó részletesen — ott az is kiderül, miért a legvégén.
// app.js app.use("/api/products", termekRouter); // routes/products.js router.get("/api/products", …); // ❌
Tünet: a végpont csak a /api/products/api/products címen
érhető el.
Megoldás: a routerben relatív útvonal: router.get("/", ...).
return a korai válasz utánif (!termek) { res.status(404).json({ error: "Nincs ilyen termék." }); // ❌ nincs return } res.json(termek); // lefut ez is
Tünet: ERR_HTTP_ a terminálban. A 2. fejezetben
már láttuk — Expressben is ugyanez a szabály: egy kérésre egy válasz.
Elméleti
Adott ez a sorrend:
app.get("/api/products/:id", A); app.get("/api/products/akcios", B); app.get("/api/products", C);
Melyik függvény fut le a GET /api/products/akcios kérésre? Miért? Hogyan
javítanád?
Döntsd el mindegyikről, útvonalparaméter vagy query paraméter legyen, és indokold:
Miért nem talál soha semmit?
app.get("/api/products/:id", (req, res) => { const termek = termekek.find(t => t.id === req.params.id); if (!termek) return res.status(404).json({ error: "Nincs ilyen." }); res.json(termek); });
A következő négy sor mind hibát dob. Írd át mindegyiket működő alakra, és írd le, mit jelentett eredetileg:
app.get("*", …); app.get("/kepek/*", …); app.get("/users/:id?", …); app.get("/:id(\d+)", …);
Írd le egy blog API végpontjait (bejegyzések és hozzászólások), metódussal és útvonalmintával együtt.
A hozzászólások egy bejegyzéshez tartoznak — ezt is fejezze ki az útvonal! Jelöld meg, melyik végponthoz
kellene mergeParams.
Gyakorlati
Készíts egy app.js-t, amiben mind a hat termék-végpont szerepel (az
1. szakasz listája szerint), és mindegyik egy rövid JSON-nal válaszol, amiből kiderül, melyik futott le.
Próbáld ki mindet REST Clienttel!
Készítsd el a GET /api/products/:id végpontot egy memóriában tárolt tömbbel.
Kezelje helyesen:
200 + a termék404 + hibaüzenet/api/products/alma) → 400 + hibaüzenetBővítsd a GET /api/products végpontot:
?categoryId=3 → csak az adott kategória termékei?q=egér → névre szűrés (kis- és nagybetű nélkül)?page=2&limit=5 → lapozás, alapértékekkelA válasz tartalmazza a találatok összes számát is, ne csak az aktuális oldalt!
Szervezd át a G1–G3 megoldásodat: hozz létre egy routes/products.js fájlt
express.Router()-rel, és akaszd fel az app.js-ben
a /api/products előtag alá. Ellenőrizd, hogy minden végpont ugyanúgy működik,
mint előtte!
Készíts egy routes/categories.js routert, benne:
GET /api/categories → kategóriák listájaGET /api/categories/:id → egy kategóriaGET /api/categories/:id/products → az adott kategória termékeiA harmadik végpontot oldd meg külön routerrel,
mergeParams: true beállítással!
:id) azt mondja meg,
melyik erőforrásról van szó; a query paraméter
(?page=2) azt, hogyan kérjük.req.params.id és a
req.query.page értéke "42" és
"2" — ha számként kell, Number()-rel alakítjuk
át, és ellenőrizzük az eredményt.req.query értéke lehet tömb (ismételt kulcs) és
üres szöveg (érték nélküli kulcs) is — mindkettőre fel kell készülni.* helyett
/*splat, :id? helyett
{/:id}, a mintába írt reguláris kifejezés pedig megszűnt. A hibák
indításkor derülnek ki.express.Router() erőforrásonként külön fájlba szervezi a
végpontokat; az előtag az app.use() hívásban egyetlen helyen szerepel.app.route() a metódusok láncolására, az app.all()
a minden metódusra való reagálásra való — az utóbbira általában a middleware a jobb megoldás.| Fogalom | Jelentés |
|---|---|
| Útvonal (route) | Metódus + útvonalminta + kezelőfüggvény hármasa |
| Útvonalminta | A cím mintája, pl. /api/products/:id |
| Útvonalparaméter | A mintában :név alakban jelölt, változó szakasz |
req.params | Az útvonalparaméterek objektuma — értékei mindig szövegek |
| Query paraméter | A ? utáni rész: szűrés, rendezés, lapozás |
req.query | A query paraméterek objektuma — szöveg vagy szövegtömb értékekkel |
| Joker / splat | Több szakaszra illeszkedő minta; Express 5-ben nevet kell adni neki: /*splat |
express.Router() | Önálló útvonalgyűjtemény, ami előtag alá akasztható |
req.baseUrl | Az az előtag, ami alá a routert akasztottuk |
req.originalUrl | A kliens által kért teljes útvonal |
mergeParams | Router-beállítás: átveszi a szülő router paramétereit is |
app.route() | Egy útvonalminta, több metódus — láncolva |