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:
- Routing —
app.get("/users/:id", ...)(qo'ldaif/elseo'rniga — 5.5). - Middleware — so'rov-javob "quvuri"da bajariladigan funksiyalar (Express'ning yuragi va eng kuchli g'oyasi).
- Qulayliklar —
req.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):
Muhim: Express — "sehr" emas. U
http5.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
npm init -y # (5.2)
npm install express # dependencies (5.2)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):
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 metodlarHar 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):
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):
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.queryvsreq.params:params— yo'ldagi dinamik qism (/users/:idreq.params.id);query—?dan keyingi (?page=2req.query.page). Ikkalasi ham string (Number'ga aylantirish kerak — 2.6).
2.6. res obyekti — javob qaytarish (5.5 + qulayliklar)
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 vaContent-Type: application/jsonni avtomatik qo'yadi (5.5'da qo'lda qilgan ikki ish — bitta metod).
2.7. Middleware — ta'rif va falsafa (Express yuragi)
Middleware — req, res va next ga ega bo'lgan funksiya; so'rov-javob "siklida" (request-response cycle) bajariladi (expressjs.com). Middleware uch narsani qila oladi:
- Kod bajaradi (log, tekshiruv).
req/resni o'zgartiradi (masalanreq.userqo'shadi).- Siklni tugatadi (
res.send) yoki keyingisiga o'tadi (next()).
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):
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):
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.bodyyo'q edi).express.json()middleware buni avtomatik qiladi: JSON body'ni parse qilib,req.bodyga qo'yadi. Usiz —req.bodyundefined!
2.10. app.use — middleware ulash
app.use(mw) — middleware'ni ulaydi (expressjs.com):
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:
npm install cors helmet morgan compressionimport 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):
// 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). Hattonextishlatilmasa 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):
// 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:
// 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-errorspaketi (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):
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 birlashtirNega 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:
// ... 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
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)
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)
// 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)
// 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)
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)
// 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)
// 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)
// 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)
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 borMisol 9 — res metodlari (2.6)
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 olishMisol 10 — Route guruhlash (app.route — 2.3)
// 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)
// 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
// 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
// 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
// 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
// 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
// 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 —
httpustiga 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.jsonbilan 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)
- Loyiha tuzilmasi:
routes/,controllers/,services/,middleware/,app.js2.16-bob. - Built-in middleware:
express.json,express.urlencoded,express.static2.9-bob; to'g'ri tartibda 2.8-bob. - Third-party:
cors,helmet,morgan2.12-bob. - Resurs (CRUD): kamida bitta resurs (masalan
tasks) — GET/GET:id/POST/PUT/DELETE;express.Routerbilan (2.14, Misol 7). - Custom middleware: logger 2.7-bob, va auth (himoyalangan route uchun — 5.15 g'oyasi).
- Validatsiya middleware: body'ni tekshiruvchi, qayta ishlatiladigan (Misol 11, 5.9).
- Error handling: custom error class + 4-argumentli error middleware + async wrapper (Misol 6, 2.13, 2.15).
- 404 handler: noma'lum yo'lga 2.17-bob.
- Status kodlar: to'g'ri (200/201/204/400/401/404 — 0.4); izchil JSON javob shakli (
{data}/{xato}). - 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/catchyokiasyncWrap2.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.Routerbilan. - 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:
- Express —
http5.5-bob ustiga qulaylik: routing, middleware,req.body/params/query,res.json. - Routing:
app.get/post/..., route param (:idreq.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 middleware — 4 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!