WisarWisar
Dasturlash kitobi/5-QISM — Nodejs20 daqiqa

5.6-bob: Express.js — routing, middleware (chuqur), req/res, router, static fayllar

5-QISM — Node.js Backend · 6-mavzu


1. Kirish va motivatsiya

5.5-bobda sof http modul bilan server yozdik — va uning og'irligini his qildik: routing qo'lda if/else, body'ni stream'dan qo'lda o'qish, query'ni qo'lda parse, takrorlanuvchi kod. Endi bularning hammasini engillashtiradigan vositani — Express.jsni o'rganamiz. Bu — Node backend'ning eng mashhur, eng ko'p ishlatiladigan frameworki va kitobning eng amaliy boblaridan biri.

Express — minimalist, moslashuvchan Node.js web framework. U http modul (5.5) ustiga qurilgan va unga uchta katta qulaylik qo'shadi:

  1. Routingapp.get("/users/:id", ...) (qo'lda if/else o'rniga — 5.5).
  2. Middleware — so'rov-javob "quvuri"da bajariladigan funksiyalar (Express'ning yuragi va eng kuchli g'oyasi).
  3. Qulayliklarreq.body, req.params, req.query, res.json() (5.5'da qo'lda qilgan narsalar avtomatik).

Middleware — bu bobning markaziy tushunchasi. U shunchaki "funksiya" emas — u Express'ning butun arxitekturasi, falsafasi. Auth, logging, validatsiya, error handling — hammasi middleware. Buni chuqur tushunsangiz, Express (va undan keyin NestJS — 8) sizga ochiq kitob bo'ladi.

O'xshatish (middleware): so'rov — aeroportga kelgan yo'lovchi. Middleware'lar — tekshiruv punktlari ketma-ket: pasport nazorati (auth), bagaj tekshiruvi (validatsiya), xavfsizlik (helmet), qayd (logging). Har punkt yo'lovchini keyingisiga o'tkazadi (next()) yoki to'xtatadi (rad javob). Oxirida — samolyot (route handler — javob). So'rov shu "quvur"dan oqib o'tadi.

Nega muhim?

  • Har Node backend — Express yoki uning g'oyalari (NestJS — 8 ham middleware/pipe).
  • Middleware — auth 5.15-bob, validatsiya 5.9-bob, error handling 5.10-bob, CORS 5.20-bob — hammasi shu.
  • Routing/req/res — REST API 5.7-bob ning amaliy asosi.
  • 5.5'dagi qo'lda qilgan ish — endi toza, qayta ishlatiladigan kod.

2. Nazariya — chuqur tushuntirish

2.1. Express nima va http bilan bog'lanish

Express — http modul (5.5) ustiga qurilgan framework. Pardaning ortida u http.createServer ni chaqiradi 5.5-bob; req/res — o'sha IncomingMessage/ServerResponse 5.5-bob, lekin Express ularga qo'shimcha metodlar qo'shadi (res.json, req.params):

text
  HTTP so'rov 0.4-bob  Node http 5.5-bob  Express  middleware quvuri  route handler  javob

Muhim: Express — "sehr" emas. U http 5.5-bob ustiga qulaylik qatlami. 5.5'ni o'tganingiz uchun endi har bir Express qulayligi ortida nima borligini bilasiz.

2.2. O'rnatish va minimal ilova

bash
npm init -y                  # (5.2)
npm install express          # dependencies (5.2)
js
import express from "express";   // (2.14: ESM; package.json type:module — 5.2)

const app = express();           // Express ilovasi (application obyekti)

app.get("/", (req, res) => {     // route: GET / (2.3)
  res.send("Salom, Express!");   // javob (res.send — 2.6)
});

app.listen(3000, () => {         // server'ni ishga tushir (5.5: listen)
  console.log("Server http://localhost:3000 da");
});

5.5'dagi http.createServer + qo'lda routing — endi app.get(...). Ancha toza.

2.3. Routing — yo'l + metod (5.5'ni almashtiradi)

Routing — qaysi URL + metodga 0.4-bob qaysi handler ishlashi. Express buni deklarativ qiladi (expressjs.com):

js
app.get("/users", handler);       // GET /users (0.4: o'qish)
app.post("/users", handler);      // POST /users (yaratish)
app.put("/users/:id", handler);   // PUT (to'liq yangilash)
app.patch("/users/:id", handler); // PATCH (qisman)
app.delete("/users/:id", handler);// DELETE (o'chirish)
app.all("/x", handler);           // barcha metodlar

Har metod — HTTP metodi 0.4-bob; har handler — (req, res) funksiya. 5.5'dagi if (req.method === "GET" && req.url === "/users") — endi app.get("/users", ...).

2.4. Route parametrlar (:id)

Route parameter — URL'dagi dinamik qism (:id); req.params orqali olinadi (expressjs.com — 5.5'da qo'lda split qilardik):

js
app.get("/users/:id", (req, res) => {
  const id = req.params.id;        // /users/42  "42" (5.5'dagi qo'lda parse o'rniga)
  res.send(`Foydalanuvchi: ${id}`);
});

// Bir nechta parametr
app.get("/users/:userId/posts/:postId", (req, res) => {
  const { userId, postId } = req.params;   // (2.8: destructuring)
});

2.5. req obyekti — to'liq (5.5 + qulayliklar)

Express req (5.5: IncomingMessage) ga qulay xususiyatlar qo'shadi (expressjs.com):

js
req.params       // route parametrlar: /users/:id  { id: "42" } (2.4)
req.query        // query string: /search?q=x&page=2  { q: "x", page: "2" } (5.5'da qo'lda)
req.body         // so'rov body (JSON/form) — express.json() KERAK (2.9)
req.headers      // headerlar (0.4)
req.method       // "GET" (0.4)
req.path         // "/users" (query'siz)
req.cookies      // cookie (cookie-parser kerak — 5.15)
req.ip           // client IP (0.4)

req.query vs req.params: params — yo'ldagi dinamik qism (/users/:id req.params.id); query? dan keyingi (?page=2 req.query.page). Ikkalasi ham string (Number'ga aylantirish kerak — 2.6).

2.6. res obyekti — javob qaytarish (5.5 + qulayliklar)

js
res.send("matn");                 // matn/HTML (Content-Type avtomatik)
res.json({ ism: "Ali" });         // JSON (5.5'da qo'lda JSON.stringify + header)
res.status(201).json({...});      // status + JSON (zanjirlanadi — 0.4)
res.status(404).send("Topilmadi");
res.sendFile(path);               // fayl yuborish (5.5'da stream qo'lda)
res.redirect("/login");           // boshqa URL'ga yo'naltir (0.4: 3xx)
res.set("X-Custom", "v");         // header (5.5: setHeader)
res.cookie("token", "...");       // cookie o'rnatish (5.15)

res.json() — eng ko'p ishlatiladigan (API uchun): obyektni JSON'ga aylantiradi va Content-Type: application/json ni avtomatik qo'yadi (5.5'da qo'lda qilgan ikki ish — bitta metod).

2.7. Middleware — ta'rif va falsafa (Express yuragi)

Middlewarereq, res va next ga ega bo'lgan funksiya; so'rov-javob "siklida" (request-response cycle) bajariladi (expressjs.com). Middleware uch narsani qila oladi:

  1. Kod bajaradi (log, tekshiruv).
  2. req/resni o'zgartiradi (masalan req.user qo'shadi).
  3. Siklni tugatadi (res.send) yoki keyingisiga o'tadi (next()).
js
const middleware = (req, res, next) => {
  // 1. kod (masalan log)
  console.log(`${req.method} ${req.url}`);
  // 2. req'ni o'zgartirish (masalan)
  req.vaqt = Date.now();
  // 3. keyingisiga o'tish (MAJBURIY — aks holda so'rov "osiladi")
  next();
};

Eng muhim qoida: middleware next() ni chaqirishi YOKI javob yuborishi (res.send/res.json) kerak. Aks holda so'rov "osilib" qoladi (brauzer kutadi — 5.5). Bu — eng ko'p uchraydigan Express xatosi.

2.8. Request lifecycle — so'rovning sayohati

So'rov Express'da quvur (pipeline) bo'ylab o'tadi; middleware'lar ro'yxatga olingan tartibda ishlaydi (expressjs.com):

text
  So'rov 0.4-bob
     │
     ▼
  [1. express.json()]    ── body parse 2.9-bob
     │ next()
     ▼
  [2. logger]            ── log 2.7-bob
     │ next()
     ▼
  [3. auth]              ── token tekshir 5.15-bob; xato  to'xtat (401)
     │ next()
     ▼
  [4. route handler]     ── GET /users  javob (res.json)
     │
     ▼
  Javob 0.4-bob
  (xato bo'lsa  error-handling middleware — 2.13)

2.9. Built-in middleware (5.5 muammolarini hal qiladi)

Express'ning o'rnatilgan middleware'lari (expressjs.com):

js
app.use(express.json());                 // JSON body parse  req.body (5.5'da qo'lda stream!)
app.use(express.urlencoded({ extended: true }));  // form body (HTML form — 1.1)
app.use(express.static("public"));       // static fayl (5.5'da stream qo'lda)

express.json() — eng muhim: 5.5-bobda body'ni stream chunk'laridan qo'lda o'qigandik (req.body yo'q edi). express.json() middleware buni avtomatik qiladi: JSON body'ni parse qilib, req.bodyga qo'yadi. Usiz — req.body undefined!

2.10. app.use — middleware ulash

app.use(mw) — middleware'ni ulaydi (expressjs.com):

js
app.use(mw);                  // BARCHA so'rovga (har metod, har yo'l)
app.use("/admin", mw);        // faqat /admin* yo'liga
app.use("/api", router);      // router ulash (2.14)
app.get("/x", mw1, mw2, handler);  // FAQAT shu route'ga (bir nechta)

2.11. Middleware turlari (5 tur)

Express'da besh tur middleware (expressjs.com):

Tur Misol
Application-level app.use(...) — butun ilovaga (2.10)
Router-level router.use(...) — bitta router'ga (2.14)
Built-in express.json, express.static (2.9)
Third-party cors, helmet, morgan (2.12)
Error-handling (err, req, res, next) — 4 argument (2.13)

2.12. Third-party middleware (npm)

Tashqi middleware'lar — npm 5.2-bob bilan o'rnatilib, qo'shiladi:

bash
npm install cors helmet morgan compression
js
import cors from "cors";          // CORS (0.4, 5.20) — boshqa domen so'rovi
import helmet from "helmet";      // xavfsizlik headerlari (14)
import morgan from "morgan";      // HTTP so'rov logging
import compression from "compression";  // javobni siqish (gzip — 5.4)

app.use(cors());                  // barcha domenga ruxsat (sozlanadi — 5.20)
app.use(helmet());                // xavfsizlik headerlari avtomatik
app.use(morgan("dev"));           // har so'rovni loglaydi
app.use(compression());           // javoblarni siqadi (tezroq — 0.4)

2.13. Error-handling middleware (4 argument!)

Error-handling middleware — boshqalardan farqli, 4 argument (err, req, res, next); Express uni xato handler deb taniydi (expressjs.com):

js
//  TO'RT argument — shuning uchun Express buni error handler deb biladi
app.use((err, req, res, next) => {
  console.error(err.stack);                          // log (2.12)
  res.status(err.status || 500).json({              // (0.4: 500)
    xato: err.message || "Server xatosi"
  });
});

Bu middleware eng oxirida (barcha route'lardan keyin) qo'yiladi. Route'da xato bo'lsa (yoki next(err) chaqirilsa), Express oddiy middleware'larni o'tkazib, to'g'ridan shu error handler'ga sakraydi (5.10-bobda chuqur).

4 argument SHART: agar next (4-argument) yozilmasa, Express uni oddiy middleware deb o'ylaydi va xatolarni ushlamaydi (expressjs.com). Hatto next ishlatilmasa ham, yozish kerak.

2.14. express.Router — modular routing (mini-app)

Katta ilovada barcha route'ni bitta faylga yozish — chalkash. express.Router — route'larni modullarga 2.14-bob ajratadi; har router — "mini-ilova" (expressjs.com):

js
// routes/users.js
import { Router } from "express";
const router = Router();

router.get("/", getAllUsers);        // GET /users (prefiks app'da)
router.get("/:id", getUserById);     // GET /users/:id
router.post("/", createUser);        // POST /users
export default router;

// app.js
import usersRouter from "./routes/users.js";
app.use("/users", usersRouter);      // /users*  usersRouter (2.10)

Nega Router: loyiha o'sgan sari route'lar ko'payadi. Router bilan har resurs (users, products, orders) alohida faylda — toza, boshqarib bo'ladigan 15.1-bob. Bu — loyiha tuzilmasining 2.16-bob asosi.

2.15. Async error handling (muhim nuans)

Express avtomatik async 2.11-bob xatolarni ushlamaydi (eski Express'da). Async handler'da xato bo'lsa, uni qo'lda next(err)ga uzatish kerak:

js
//  async xato ushlanmaydi  server osiladi yoki qulaydi (2.11, 5.10)
app.get("/x", async (req, res) => {
  const data = await DB.query();    // xato bo'lsa — ushlanmaydi!
  res.json(data);
});

//  try/catch + next(err)
app.get("/x", async (req, res, next) => {
  try {
    const data = await DB.query();
    res.json(data);
  } catch (err) {
    next(err);                       // error handler'ga uzat (2.13)
  }
});

//  Yoki wrapper (takrorlanishni kamaytiradi — 2.15-best practice)
const asyncWrap = (fn) => (req, res, next) => fn(req, res, next).catch(next);
app.get("/x", asyncWrap(async (req, res) => {
  res.json(await DB.query());        // xato avtomatik next(err)ga (2.11)
}));

Eslatma: Express 5'da async xatolar avtomatik ushlanadi. Lekin Express 4 (hali keng) — wrapper kerak. Muqobil: express-async-errors paketi (import qilinsa, async handler'dagi xatolar avtomatik error handler'ga uzatiladi — wrapper'siz). NestJS (8) buni butunlay hal qiladi.

2.16. Loyiha tuzilmasi (MVC g'oyasi)

Professional Express loyihasi — qatlamlarga bo'linadi (9.3: layered):

text
  src/
   ├── routes/          URL  controller 2.14-bob
   ├── controllers/     so'rovni qabul qil, javob qaytar (req/res)
   ├── services/        biznes logika (DB, hisob — req/res'siz)
   ├── models/          ma'lumot modeli (6: DB)
   ├── middleware/      auth, validatsiya, error 2.7-bob
   ├── config/          sozlama 5.8-bob
   └── app.js           hammasini birlashtir

Nega ajratish: controller — so'rov/javob bilan ishlaydi (req/res); service — biznes logika (DB, hisob) — req/resni bilmaydi (test qilish oson, qayta ishlatiladi). Bu — Single Responsibility 9.1-bob va Clean Architecture 9.3-bob ga tayyorgarlik.

2.17. 404 va so'rov tartibi

Express middleware/route'lar tartib bilan 2.8-bob ishlaydi. Hech bir route mos kelmasa — 404. Buni eng oxirgi middleware bilan ushlaymiz:

js
// ... barcha route'lardan KEYIN
app.use((req, res) => {              // hech bir route mos kelmadi
  res.status(404).json({ xato: "Yo'l topilmadi" });   // (0.4: 404)
});
// keyin error handler (2.13)

3. Sintaksis — tez ma'lumotnoma

js
import express from "express";
const app = express();

// Built-in middleware (2.9)
app.use(express.json());            // req.body (JSON)
app.use(express.static("public"));  // static fayl

// Routing (2.3, 2.4)
app.get("/users/:id", (req, res) => res.json({ id: req.params.id }));
app.post("/users", (req, res) => res.status(201).json(req.body));

// Middleware 2.7-bob — next() yoki javob!
app.use((req, res, next) => { /* ... */ next(); });

// Router (2.14)
import { Router } from "express";  const r = Router();  app.use("/api", r);

// Error handler 2.13-bob — 4 argument, ENG OXIRDA
app.use((err, req, res, next) => res.status(500).json({ xato: err.message }));

app.listen(3000);

4. Batafsil kod namunalari

Misol 1 — Minimal Express ilova (2.2)

js
import express from "express";
const app = express();

app.use(express.json());            // JSON body parse 2.9-bob — MUHIM

app.get("/", (req, res) => {
  res.json({ xabar: "Express ishlayapti", vaqt: Date.now() });   // (2.6)
});

app.listen(3000, () => console.log("http://localhost:3000"));

Misol 2 — Routing va parametrlar (2.3, 2.4, 2.5)

js
// Query 2.5-bob: /search?q=telefon&page=2
app.get("/search", (req, res) => {
  const { q = "", page = 1 } = req.query;          // (2.8: destructuring + default)
  res.json({ qidiruv: q, sahifa: Number(page) });  // (2.6: string  number)
});

// Route param 2.4-bob: /users/42
app.get("/users/:id", (req, res) => {
  const id = Number(req.params.id);                 // (2.4)
  if (Number.isNaN(id)) {                           // validatsiya (0.1, 2.6)
    return res.status(400).json({ xato: "ID son bo'lishi kerak" });  // (0.4: 400)
  }
  res.json({ id, ism: "Ali" });
});

// Bir nechta param (2.4)
app.get("/users/:userId/posts/:postId", (req, res) => {
  const { userId, postId } = req.params;
  res.json({ userId, postId });
});

Misol 3 — Custom middleware: logger va auth (2.7)

js
// Logger middleware 2.7-bob — har so'rovni loglaydi
const logger = (req, res, next) => {
  const boshlanish = Date.now();
  res.on("finish", () => {                          // javob tugaganda (5.4: event)
    console.log(`${req.method} ${req.url}  ${res.statusCode} (${Date.now() - boshlanish}ms)`);
  });
  next();                                            // keyingisiga (2.7: MAJBURIY)
};

// Auth middleware 5.15-bob — token tekshiradi
const auth = (req, res, next) => {
  const token = req.headers.authorization?.split(" ")[1];   // "Bearer xxx" (0.4, 2.1)
  if (!token) {
    return res.status(401).json({ xato: "Token kerak" });   // to'xtatadi (0.4: 401)
  }
  req.user = { id: 1, ism: "Ali" };                 // req'ni boyitadi (2.7)
  next();                                            // o'tkazadi
};

app.use(logger);                                    // hammaga (2.10)
app.get("/profil", auth, (req, res) => {            // faqat shu route'ga auth (2.10)
  res.json(req.user);                               // auth qo'shgan (2.7)
});

Misol 4 — Built-in va third-party middleware (2.9, 2.12)

js
import express from "express";
import cors from "cors";
import helmet from "helmet";
import morgan from "morgan";

const app = express();

// Tartib MUHIM 2.8-bob — yuqoridan pastga
app.use(helmet());                       // xavfsizlik headerlari (14)
app.use(cors({ origin: "https://mysite.com" }));   // CORS (5.20)
app.use(morgan("dev"));                  // logging (2.12)
app.use(express.json());                 // JSON body (2.9)
app.use(express.urlencoded({ extended: true }));   // form body (2.9)
app.use(express.static("public"));       // static fayl (2.9)

// ... route'lar ...

Misol 5 — express.Router (modular — 2.14)

js
// routes/products.js
import { Router } from "express";
const router = Router();

// Router-level middleware 2.11-bob — faqat shu router'ga
router.use((req, res, next) => {
  console.log("Products router'iga so'rov");
  next();
});

router.get("/", (req, res) => res.json([{ id: 1, nom: "Telefon" }]));
router.get("/:id", (req, res) => res.json({ id: req.params.id }));
router.post("/", (req, res) => res.status(201).json(req.body));

export default router;

// app.js
import productsRouter from "./routes/products.js";
app.use("/products", productsRouter);    // /products*  router (2.10, 2.14)
// GET /products  router'dagi "/"; GET /products/5  "/:id"

Misol 6 — Error handling middleware (2.13, 2.15)

js
// Custom error class (2.12-JS: 2.12)
class AppError extends Error {
  constructor(message, status) {
    super(message);
    this.status = status;
  }
}

// async wrapper 2.15-bob — try/catch takrorlanishini kamaytiradi
const asyncWrap = (fn) => (req, res, next) => fn(req, res, next).catch(next);

app.get("/users/:id", asyncWrap(async (req, res) => {
  const user = await topUser(req.params.id);        // DB (6)
  if (!user) throw new AppError("Foydalanuvchi topilmadi", 404);  // (2.13)
  res.json(user);
}));

// 404 handler 2.17-bob — barcha route'dan keyin
app.use((req, res) => res.status(404).json({ xato: "Yo'l topilmadi" }));

// Error handler 2.13-bob — ENG OXIRGI, 4 argument
app.use((err, req, res, next) => {
  console.error(err.stack);                          // log (2.12, 5.12)
  res.status(err.status || 500).json({              // (0.4)
    xato: err.message || "Ichki server xatosi"
  });
});

Misol 7 — To'liq mini REST API (loyiha tuzilmasi — 2.16)

js
// controllers/userController.js — so'rov/javob (2.16)
const users = [{ id: 1, ism: "Ali" }];   // (keyin DB — 6)
let nextId = 2;

export const getAll = (req, res) => res.json(users);

export const getOne = (req, res) => {
  const user = users.find(u => u.id === Number(req.params.id));   // (2.7-JS)
  if (!user) return res.status(404).json({ xato: "Topilmadi" });
  res.json(user);
};

export const create = (req, res) => {
  const { ism } = req.body;                          // (2.9: express.json kerak)
  if (!ism) return res.status(400).json({ xato: "Ism kerak" });   // validatsiya (5.9)
  const yangi = { id: nextId++, ism };
  users.push(yangi);
  res.status(201).json(yangi);                       // 201 Created (0.4)
};

// routes/userRoutes.js
import { Router } from "express";
import { getAll, getOne, create } from "../controllers/userController.js";
const router = Router();
router.get("/", getAll);
router.get("/:id", getOne);
router.post("/", create);
export default router;

// app.js
import express from "express";
import userRoutes from "./routes/userRoutes.js";
const app = express();
app.use(express.json());                             // (2.9)
app.use("/api/users", userRoutes);                   // (2.14)
app.use((req, res) => res.status(404).json({ xato: "Yo'l yo'q" }));   // (2.17)
app.listen(3000);

Misol 8 — Middleware tartibi (2.8 — eng ko'p tushunmaslik)

js
const app = express();

//  XATO TARTIB — json route'dan KEYIN  req.body undefined
app.post("/a", (req, res) => res.json(req.body));   // req.body undefined!
app.use(express.json());                            // kech!

//  TO'G'RI TARTIB — middleware route'dan OLDIN (2.8)
app.use(express.json());                            // avval
app.post("/b", (req, res) => res.json(req.body));   // endi req.body bor

Misol 9 — res metodlari (2.6)

js
app.get("/text", (req, res) => res.send("Oddiy matn"));        // matn
app.get("/json", (req, res) => res.json({ ok: true }));        // JSON
app.get("/created", (req, res) => res.status(201).json({...})); // status zanjir
app.get("/old", (req, res) => res.redirect("/new"));           // yo'naltirish (0.4)
app.get("/file", (req, res) => res.sendFile(path.join(import.meta.dirname, "a.pdf")));
app.get("/download", (req, res) => res.download("rasm.png"));   // yuklab olish

Misol 10 — Route guruhlash (app.route — 2.3)

js
// Bir yo'lning turli metodlarini zanjirlash
app.route("/books")
  .get((req, res) => res.json([{ id: 1 }]))          // GET /books
  .post((req, res) => res.status(201).json(req.body)); // POST /books

app.route("/books/:id")
  .get((req, res) => res.json({ id: req.params.id })) // GET /books/:id
  .put((req, res) => res.json({ updated: req.params.id }))
  .delete((req, res) => res.status(204).end());       // DELETE (0.4: 204)

Misol 11 — Validatsiya middleware (5.9 ga ko'prik)

js
// Qayta ishlatiladigan validatsiya middleware (2.7)
const validateUser = (req, res, next) => {
  const { ism, email } = req.body;                   // (2.9)
  const xatolar = [];
  if (!ism || ism.length < 2) xatolar.push("Ism kamida 2 belgi");
  if (!email?.includes("@")) xatolar.push("Email noto'g'ri");   // (2.6-JS, 2.13)
  if (xatolar.length) {
    return res.status(400).json({ xatolar });        // (0.4: 400)
  }
  next();                                              // hammasi to'g'ri (2.7)
};

app.post("/users", validateUser, (req, res) => {     // (2.10: route middleware)
  res.status(201).json(req.body);                    // validatsiyadan o'tdi
});

5. To'g'ri va noto'g'ri holatlar

1) express.json()ni unutish

js
//  req.body undefined (2.9)
app.post("/x", (req, res) => res.json(req.body));   // undefined!

//  json middleware (route'dan oldin — 2.8)
app.use(express.json());

2) next() yoki javobni unutish

js
//  so'rov osiladi (brauzer kutadi — 2.7)
app.use((req, res, next) => { console.log("..."); });   // next yo'q!

//  next() yoki res.send
app.use((req, res, next) => { console.log("..."); next(); });

3) Error handler 3 argument bilan

js
//  3 argument  oddiy middleware deb qabul qilinadi, xato ushlanmaydi (2.13)
app.use((err, req, res) => {...});

//  4 argument (next ishlatilmasa ham)
app.use((err, req, res, next) => {...});

4) Async xatoni ushlamaslik

js
//  async xato ushlanmaydi (2.15)
app.get("/x", async (req, res) => { await DB.query(); });

//  try/catch + next yoki wrapper
app.get("/x", asyncWrap(async (req, res) => {...}));

5) Middleware tartibi xato

js
//  auth route'dan keyin  himoyalanmaydi (2.8)
app.get("/admin", handler);
app.use(auth);

//  middleware route'dan oldin
app.use(auth);
app.get("/admin", handler);

6. Keng tarqalgan xatolar va yechimlari

Xato 1 — req.body undefined

Sababi: express.json() yo'q yoki route'dan keyin (2.9, 2.8). Yechimi: app.use(express.json()) route'lardan oldin.

Xato 2 — So'rov "osilib" qoladi (javob kelmaydi)

Sababi: middleware next()/javob chaqirmagan 2.7-bob. Yechimi: har middleware next() yoki res bilan tugasin.

Xato 3 — Cannot set headers after they are sent

Sababi: ikki marta javob (res.json keyin yana res.send), yoki next()dan keyin javob 5.5-bob. Yechimi: javobdan keyin return; bitta javob.

Xato 4 — Error handler xatoni ushlamaydi

Sababi: 3 argument yoki noto'g'ri joyda 2.13-bob. Yechimi: 4 argument; eng oxirda; async'da next(err) 2.15-bob.

Xato 5 — CORS policy xatosi (brauzerdan)

Sababi: boshqa domen so'rovi bloklangan (0.4, 5.20). Yechimi: app.use(cors()) (sozlangan — 5.20). Bu — server muammosi 0.4-bob.

Xato 6 — 404 hamma narsaga

Sababi: route ro'yxatdan o'tmagan yoki tartib xato 2.8-bob. Yechimi: route'larni 404 handler'dan oldin qo'y 2.17-bob.


7. Integratsiya — bu mavzu stack'ning qayerida uchraydi

  • HTTP modul 5.5-bob: Express — http ustiga qulaylik qatlami.
  • REST API 5.7-bob: Express — REST'ning amaliy asosi.
  • Validatsiya 5.9-bob: middleware sifatida (Misol 11).
  • Error handling 5.10-bob: error middleware chuqur.
  • Auth 5.15-bob: auth middleware, JWT, cookie.
  • CORS/helmet (5.20, 14): third-party middleware.
  • NestJS (8): middleware/pipe/guard — Express g'oyalari ustida.
  • Clean Architecture 9.3-bob: loyiha tuzilmasi (controller/service).

8. Eng yaxshi amaliyotlar (best practices)

  • express.json() (va kerakli middleware) route'lardan oldin (2.8, 2.9).
  • Har middleware next() yoki javob bilan tugasin 2.7-bob.
  • Error handler — 4 argument, eng oxirda 2.13-bob; async uchun wrapper 2.15-bob.
  • Loyiha tuzilmasi: routes/controllers/services ajrating (2.16, 9.1).
  • express.Router bilan modular routing 2.14-bob.
  • Third-party: helmet (14), cors 5.20-bob, morgan (logging) — boshida.
  • Status kodlar to'g'ri (201/400/404 — 0.4); res.json bilan izchil javob shakli.
  • Validatsiyani middleware sifatida (qayta ishlatiladigan — Misol 11, 5.9).
  • req.params/queryni aylantiring (string — Number/validatsiya — 2.5).
  • Express 5 yoki async wrapper — async xatolar uchun 2.15-bob.

9. Amaliy loyiha: "To'liq Express REST API (qatlamli)"

Express'ning barcha tushunchalarini birlashtirgan, professional tuzilmali API.

Maqsad

Routing, middleware (barcha turlar), req/res, Router va error handling'ni birlashtirib, qatlamli (controller/service), xavfsiz, toza REST API qurish.

Talablar (requirements)

  1. Loyiha tuzilmasi: routes/, controllers/, services/, middleware/, app.js 2.16-bob.
  2. Built-in middleware: express.json, express.urlencoded, express.static 2.9-bob; to'g'ri tartibda 2.8-bob.
  3. Third-party: cors, helmet, morgan 2.12-bob.
  4. Resurs (CRUD): kamida bitta resurs (masalan tasks) — GET/GET:id/POST/PUT/DELETE; express.Router bilan (2.14, Misol 7).
  5. Custom middleware: logger 2.7-bob, va auth (himoyalangan route uchun — 5.15 g'oyasi).
  6. Validatsiya middleware: body'ni tekshiruvchi, qayta ishlatiladigan (Misol 11, 5.9).
  7. Error handling: custom error class + 4-argumentli error middleware + async wrapper (Misol 6, 2.13, 2.15).
  8. 404 handler: noma'lum yo'lga 2.17-bob.
  9. Status kodlar: to'g'ri (200/201/204/400/401/404 — 0.4); izchil JSON javob shakli ({data} / {xato}).
  10. Query/params: filtr/sahifalash (query) va :id (params — 2.4, 2.5).

Maslahatlar (hint)

  • app.use(express.json()) route'lardan oldin (2.8, 1-xato).
  • Controller — req/res; service — biznes logika (req/ressiz — 2.16).
  • Error middleware — 4 argument, eng oxirda 2.13-bob.
  • async handler — try/catch yoki asyncWrap 2.15-bob.
  • Validatsiya — alohida middleware (Misol 11).
  • Har middleware next() yoki javob 2.7-bob.

"Tayyor" mezonlari (acceptance criteria)

  • Qatlamli tuzilma (routes/controllers/services).
  • Built-in + third-party middleware to'g'ri tartibda.
  • To'liq CRUD express.Router bilan.
  • Custom logger va auth middleware ishlaydi.
  • Validatsiya middleware noto'g'ri body'ni 400 bilan rad etadi.
  • Error handling (4-argument) + async wrapper ishlaydi.
  • 404 handler noma'lum yo'lga.
  • Status kodlar va JSON javob shakli izchil.

Yechim kodi ataylab berilmagan — bu loyihani o'zingiz yozib ko'ring.


10. Xulosa va keyingi bobga ko'prik

Bu bobda Node backend'ning eng muhim frameworkini — Expressni chuqur o'rgandik:

  • Expresshttp 5.5-bob ustiga qulaylik: routing, middleware, req.body/params/query, res.json.
  • Routing: app.get/post/..., route param (:id req.params), query (req.query).
  • Middleware (Express yuragi) — (req, res, next); next() yoki javob (majburiy); tartib muhim 2.8-bob. 5 tur: application/router/built-in/third-party/error.
  • Built-in: express.json (body — 5.5 muammosi hal!), express.static. Third-party: cors/helmet/morgan.
  • Error-handling middleware4 argument, eng oxirda; async uchun wrapper 2.15-bob.
  • express.Router — modular; loyiha tuzilmasi (controller/service — 2.16).

Keyingi bob — 5.7-bob: REST API dizayni (resurslar, metodlar, status, versiyalash, best practices). Express bilan API yozishni bildik; endi yaxshi API qanday dizayn qilinishini — RESTful prinsiplar, resurs nomlash, to'g'ri metod/status, versiyalash, sahifalash, xatolar formati — professional darajada o'rganamiz.


Foydalanilgan rasmiy/ishonchli manbalar

  • expressjs.com — Routing, Using middleware, Writing middleware, error handling
  • MDN — Express/Node introduction, Routes and controllers
  • expressjs.com — express.Router, built-in middleware (json/static/urlencoded)

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
5.6-bob: Express.js — routing, middleware (chuqur), req/res, router, static fayllar — Wisar