IlmHamroh
JavaScript Full-stack/30-qism. NestJS1/65-dars20 daqiqa
Mundarija (29)

NestJS nima va nega: Express ustidagi tartibli arxitektura

Qisqacha: NestJS — Node.js uchun server freymvorki. U HTTP'ni o'zi qabul qilmaydi: ichida Express (sukut) yoki Fastify ishlaydi. Nest ularning ustiga tartib qo'shadi: kod modullarga bo'linadi, so'rovni controller qabul qiladi, mantiq xizmatda yashaydi, obyektlarni esa Nest o'zi yaratib, kerakli joyga beradi (bog'liqlikni tashqaridan berish, DI). Bu tartib katta loyiha va jamoa uchun foydali, lekin bepul emas: kanon o'lchovida vazifalar-api Nest'da 28–33 % sekinroq javob berdi va ikki baravar sekin ishga tushdi.

Bu darsda

  • NestJS Express'dan nimasi bilan farq qilishini o'z so'zingiz bilan tushuntirasiz.
  • "Fikrli freymvork" (opinionated) va "platform adapter" nima ekanini bilasiz.
  • Nest'ning yuragi — DI konteynerni 25 qatorlik JS modelida o'zingiz ishlatib ko'rasiz.
  • Qachon Nest, qachon oddiy Express tanlashni o'lchov bilan asoslaysiz.
  • vazifalar-api ga Nest paketlarini o'rnatib, ko'chishning birinchi qadamini qo'yasiz.

Oldin bilishingiz kerak: express.Router va qatlamli loyiha tuzilmasi, Express + TypeScript, Legacy dekoratorlar va reflect-metadata, Fastify.

25–29-qismlarda vazifalar-api ni Express'da qurdik: REST, Postgres, Prisma, Redis, auth, fayllar, navbatlar. U ishlaydi va testlangan. Bu qismda yangi loyiha boshlamaymiz. Aynan shu API'ni NestJS'ga ko'chiramiz — qadamma-qadam, eski kodni buzmasdan.

Maslahat: Darsda kanon so'zi ko'p uchraydi. Kanon — bu qism uchun biz oldindan qurib, ishga tushirib, natijasini yozib olgan namunaviy loyiha va tajribalar. Darsdagi chiqishlar va o'lchovlar o'sha yozuvlardan yoki "biz ishga tushirdik" deb belgilangan o'z sinovimizdan olingan.

1. Nega bu kerak?

25-qismdagi ilova.ts ni eslang. U yerda hamma narsani qo'lda ulagandik:

ts
const xizmat = vazifaXizmati(ombor, () => joriyLog(log), xabarchi);
const v1 = express.Router();
v1.use("/vazifalar", idempotentlik(idempotentlikOmbori),
  vazifalarRouteri(xizmat, { tz }));
v1.use("/teglar", teglarRouteri(xizmat));
v1.use("/eksportlar",
  eksportRouteri(ombor, { log: () => joriyLog(log) }));
app.use("/v1", v1);

Bu kod yaxshi. Har bog'liqlik ko'rinib turibdi: xizmat omborni oladi, router xizmatni oladi. 25-qismda buni bog'liqlikni tashqaridan berish deb atagandik (qatlamlar darsi). Kutubxonasiz, oddiy funksiyalar bilan.

Endi loyiha o'sdi, deylik. 28-qismda auth qo'shildi, 29-qismda email, Telegram, navbat. Har biri o'z omborini, logini, sozlamasini so'raydi. ilova.ts uzunlashadi. Jamoaga besh dasturchi keladi va har biri papkalarni o'zicha tartiblaydi. Biri xizmatni funksiya qiladi, biri klass, uchinchisi new ni to'g'ridan router ichida yozadi.

Express bunga qarshi hech narsa demaydi. U fikrsiz (unopinionated): "qanday tuzasiz — o'zingiz bilasiz". Kichik loyihada bu erkinlik. Katta jamoada esa har bir loyiha boshqacha bo'lib ketadi.

O'xshatish: Express — bo'sh yer va g'isht. Uyni xohlagancha qurasiz. NestJS — tayyor loyiha chizmasi bilan qurilish kompaniyasi: xonalar qayerda, quvur qayerdan o'tadi — oldindan belgilangan. Erkinlik kamroq, lekin har qanday usta uyga kirib, nima qayerdaligini darrov topadi.

2. NestJS nima

2.1 Bir gapda

NestJS — Node.js uchun TypeScript'da yozilgan server freymvorki. U 2017-yilda chiqqan. Uning o'zi HTTP so'rovni o'qimaydi va javob yozmaydi. Bu ishni ichidagi HTTP kutubxonasi qiladi: sukut bo'yicha Express, xohlasangiz Fastify. Nest esa ularning ustiga arxitektura qo'yadi.

Nest hujjati o'zini shunday ta'riflaydi: Express (sukut) yoki Fastify ustida ishlaydi va "tayyor ilova arxitekturasini" beradi, u Angulardan kuchli ilhomlangan. Angular — Google'ning frontend freymvorki (kursda alohida tanishamiz, hozir bilish shart emas). Undan Nest uchta g'oyani olgan: modullar, DI va dekoratorlar.

2.2 Fikrli freymvork (opinionated framework)

Fikrli freymvork (opinionated framework) — "buni qanday qilish kerak" degan savolga oldindan javob bergan freymvork. Nest'da javoblar tayyor:

Savol Express'da Nest'da
Kod qanday bo'linadi? o'zingiz tanlaysiz modul (module)
So'rovni kim qabul qiladi? router funksiyasi controller klassi
Biznes mantiq qayerda? xohlagan joyda xizmat (service) klassi
Bog'liqliklar qanday ulanadi? qo'lda, ilova.ts da Nest o'zi (DI)
Validatsiya, xato, log? middleware, o'z kodingiz pipe, filter, interceptor

Jadvalga qarang: chap ustundagi "o'zingiz tanlaysiz" o'rniga Nest'da aniq nom bor. Bu nomlar har Nest loyihasida bir xil. Boshqa kompaniyaning Nest kodini ochsangiz ham, *.module.ts, *.controller.ts, *.service.ts fayllarni ko'rasiz.

Oxirgi qatordagi pipe, filter, interceptor — keyingi darslarda alohida o'rganiladi. Hozir bilish shart emas.

2.3 Platform adapter

Nest bilan HTTP kutubxonasi orasida yupqa qatlam bor — platform adapter (platforma moslagichi). U Nest'ning umumiy buyruqlarini ("shu yo'lga shu funksiyani ula", "javobni yubor") Express yoki Fastify tiliga tarjima qiladi.

flowchart TB
  M["Mijoz: curl, brauzer"] -->|HTTP| H["Node http server"]
  H --> A["Platform adapter"]
  A --> E["Express (sukut)"]
  A -.-> F["Fastify (ixtiyoriy)"]
  E --> N["Nest yadrosi: router, DI"]
  F -.-> N
  N --> C["Controller"]
  C --> S["Xizmat"]
  S --> O["Ombor (Postgres, Prisma)"]

Diagrammani yuqoridan pastga o'qing. So'rov baribir Node'ning http serveriga keladi (http.createServer darsi). Express uni qabul qiladi, keyin Nest yadrosi qaysi controller'ga berishni hal qiladi. Pastdagi uch qatlam — controller, xizmat, ombor — 25-qismdagi uch qatlamning aynan o'zi. Nest ularni majburiy qiladi.

Adapter almashtiriladigan bo'lgani uchun controller va xizmat kodingiz Express'ni bilmaydi (to'g'ri yozilsa). Fastify'ga o'tish — asosan bitta qator. Buni Fastify adapter bilan NestJS darsida o'lchaymiz.

Tekshirib ko'ring: "NestJS Express'ning o'rnini bosadi" degan gap to'g'rimi?

Javob

Yo'q. Nest Express'ni ichida ishlatadi. vazifalar-api ning Nest versiyasida ham express paketi bor va helmet, cors kabi Express middleware'lari ishlashda davom etadi. Nest — Express ustidagi qavat, uning o'rnidagi narsa emas.

3. Uch asosiy g'isht

3.1 Modul, controller, xizmat

Nest ilovasi uch turdagi klassdan yig'iladi. Har biri — bitta vazifa:

  • Modul (module) — bir mavzuga tegishli kodni o'rab turuvchi quti. Masalan, VazifalarModule — vazifalar bilan bog'liq hamma narsa. Modul nimani tashqariga berishini ham belgilaydi.
  • Controller — HTTP so'rovni qabul qiladi, xizmatni chaqiradi, javob qaytaradi. 25-qismdagi marshrut.ts ning o'rni.
  • Xizmat (service) — biznes qoidalari: "1000 tadan ko'p vazifa bo'lmaydi", "versiya mos kelmasa 412". 25-qismdagi xizmat.ts ning o'rni.

Xizmat Nest tilida provider turidagi narsa. Provider (ta'minlovchi) — Nest yaratib, boshqalarga bera oladigan har qanday obyekt: xizmat, ombor, logger, sozlamalar. Xizmat — provider'ning eng ko'p uchraydigan turi.

3.2 Dekoratorlar — Nest'ga yozilgan yorliqlar

Nest kodida har klass ustida @ bilan boshlanadigan qator bor. Bu dekorator (decorator) — legacy dekoratorlar darsida o'rgangansiz. Nest'da dekorator klassga yorliq yopishtiradi: "bu controller", "bu GET marshrut".

nest new yaratgan eng kichik controller (CLI 12.0.9, biz ishga tushirdik):

ts
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service.js';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }
}

Qatorma-qator:

  • @Controller() — "bu klass controller". Qavs ichida yo'l bo'lsa (@Controller("vazifalar")), hamma marshrut shu yo'l bilan boshlanadi.
  • constructor(private readonly appService: AppService) — controller'ga xizmat kerak. Lekin uni hech kim new AppService() qilib yaratmayapti. Uni Nest beradi.
  • @Get() — "GET so'rovida shu metodni chaqir".
  • return ... — qaytgan qiymat javob tanasi bo'ladi. res.json() yozilmaydi.

Bu kod saytdagi «Ishga tushir» tugmasida ishlamaydi. Nest dekoratorlari va ular yozadigan metama'lumot uchun loyihani build qilish kerak — buni keyingi darsda ko'ramiz. Shuning uchun bu qismdagi Nest kodi — o'qish uchun, natijasi esa kanon yoki o'z sinovimizdan.

Shu loyihani biz build qilib, fetch bilan ikki so'rov yubordik (Node 24.21.0, NestJS 12.2.0). Server boshida Nest o'z logini chiqardi (jarayon raqami va vaqtni olib tashladik):

text
LOG [NestFactory] Starting Nest application...
LOG [InstanceLoader] AppModule dependencies initialized +9ms
LOG [RoutesResolver] AppController {/}: +10ms
LOG [RouterExplorer] Mapped {/, GET} route +4ms
LOG [NestApplication] Nest application successfully started +2ms
GET / → 200
  content-type: text/html; charset=utf-8
  x-powered-by: Express
  Hello World!
GET /yoq → 404
  content-type: application/json; charset=utf-8
  x-powered-by: Express
  {"message":"Cannot GET /yoq","error":"Not Found","statusCode":404}

Uchta narsaga qarang. Birinchidan, Mapped {/, GET} route — Nest dekoratorlarni o'qib, marshrutlar jadvalini o'zi tuzdi. Ikkinchidan, x-powered-by: Express — ichida haqiqatan Express ishlayapti. Uchinchidan, 404 javobi Nest'ning o'z formati: Problem Details emas (Problem Details darsi). vazifalar-api da uni o'zimizning formatga qaytaramiz — buni xato filtrlari darsida batafsil ko'ramiz.

Tekshirib ko'ring: AppController ichida new AppService() yo'q. Unda this.appService qayerdan keldi?

Javob

Nest o'zi yaratdi va constructor'ga berdi. Nest AppController ning constructor'iga qaradi, unga AppService kerakligini metama'lumotdan o'qidi, AppService dan bitta nusxa yaratdi va berdi. Bu — bog'liqlikni tashqaridan berish. Keyingi bo'limda uni o'zimiz yozib ko'ramiz.

4. Nest'ning yuragi: DI konteyner

4.1 Bog'liqlikni tashqaridan berish va IoC

Bog'liqlikni tashqaridan berish (dependency injection, DI) — obyekt o'ziga kerak narsani o'zi yaratmaydi, tashqaridan oladi. Bu nom bilan 11-qismda tanishgansiz, 25-qismda "bog'liqlik ukoli" deb ham aytgandik — g'oya o'sha. Farq — kim beradi:

  • Express'da — siz, ilova.ts da qo'lda: vazifaXizmati(ombor).
  • Nest'da — IoC konteyner.

IoC (inversion of control — boshqaruvni teskari berish) — obyektlarni yaratish va ulash ishini sizning kodingiz emas, freymvork bajaradi. Siz faqat "menga nima kerak" deb aytasiz. IoC konteyner — shu ishni bajaradigan qism: qaysi klass nimaga muhtojligini biladi, kerakli tartibda yaratadi va tayyor nusxalarni saqlaydi.

O'xshatish: to'yxona oshxonasi. Oshpaz (controller) "menga guruch, go'sht, sabzi kerak" deydi. U bozorga o'zi bormaydi. Ta'minotchi (konteyner) hammasini olib keladi. Ertaga guruchni boshqa bozordan olish kerak bo'lsa, oshpazni o'zgartirmaysiz — ta'minotchiga boshqa manzil berasiz.

4.2 25 qatorlik JS modeli

Haqiqiy Nest konteyneri murakkab. Lekin g'oyasi kichik. Uni dekoratorsiz, oddiy JavaScript'da yozamiz — bu blok brauzerda ham ishlaydi. Nest bog'liqliklarni metama'lumotdan o'qiydi, biz esa ularni qosh() ga qo'lda yozamiz:

js
class Konteyner {
  #royxat = new Map(); // klass → kerakli klasslar
  #tayyor = new Map(); // klass → yagona nusxa

  qosh(Klass, kerak = []) {
    this.#royxat.set(Klass, kerak);
  }

  ol(Klass) {
    if (this.#tayyor.has(Klass)) return this.#tayyor.get(Klass);
    const kerak = this.#royxat.get(Klass);
    if (!kerak) throw new Error(`${Klass.name} ro'yxatda yo'q`);
    const argumentlar = kerak.map((K) => this.ol(K));
    const nusxa = new Klass(...argumentlar);
    this.#tayyor.set(Klass, nusxa);
    console.log(`yaratildi: ${Klass.name}`);
    return nusxa;
  }
}

class Ombor {
  royxat() { return ["Non olish", "Choy damlash"]; }
}
class VazifalarXizmati {
  constructor(ombor) { this.ombor = ombor; }
  royxat() { return this.ombor.royxat(); }
}
class VazifalarController {
  constructor(xizmat) { this.xizmat = xizmat; }
  get() { return { vazifalar: this.xizmat.royxat() }; }
}
class TeglarController {
  constructor(xizmat) { this.xizmat = xizmat; }
}

const k = new Konteyner();
k.qosh(Ombor);
k.qosh(VazifalarXizmati, [Ombor]);
k.qosh(VazifalarController, [VazifalarXizmati]);
k.qosh(TeglarController, [VazifalarXizmati]);

console.log(k.ol(VazifalarController).get());
const t = k.ol(TeglarController);
console.log(t.xizmat === k.ol(VazifalarXizmati));

Konsolda:

text
yaratildi: Ombor
yaratildi: VazifalarXizmati
yaratildi: VazifalarController
{ vazifalar: [ 'Non olish', 'Choy damlash' ] }
yaratildi: TeglarController
true

Chiqishni tartib bilan o'qing:

  1. ol(VazifalarController) — controller'ga xizmat kerak, xizmatga ombor kerak. Konteyner pastdan yuqoriga yaratdi: avval Ombor, keyin xizmat, keyin controller.
  2. TeglarController ham xizmatni so'radi. Lekin yaratildi: VazifalarXizmati ikkinchi marta chiqmadi — konteyner tayyor nusxani berdi.
  3. true — ikki controller bitta xizmat nusxasini ishlatyapti.

Ikkinchi va uchinchi punkt Nest'da ham aynan shunday: provider sukut bo'yicha singleton — butun ilova uchun bitta nusxa. Bu juda muhim: 25-qismdagi eksport ishlari Map da saqlanardi. Ikki xil nusxa bo'lsa, ma'lumot ikkiga bo'linib ketardi.

flowchart LR
  VC["VazifalarController"] --> VS["VazifalarXizmati (1 nusxa)"]
  TC["TeglarController"] --> VS
  VS --> O["Ombor (1 nusxa)"]

Diagrammadagi ikki strelka bitta qutiga kelyapti — bu singleton. DI va IoC konteyner darsida haqiqiy konteynerni chuqur ko'ramiz.

Tekshirib ko'ring: Modelda k.qosh(Ombor) qatorini o'chirsak, k.ol(VazifalarController) qanday xato beradi?

Javob

Error: Ombor ro'yxatda yo'q. Konteyner controller → xizmat → ombor zanjiri bo'ylab tushadi va omborni topmaydi. Nest'da ham xuddi shu holat bor, faqat xabari uzunroq: Nest can't resolve dependencies of the .... Uni Modullar darsida haqiqiy chiqish bilan ko'ramiz.

4.3 Nest qayerdan biladi?

Bizning modelda [Ombor] ni qo'lda yozdik. Nest'da esa siz faqat constructor yozasiz: constructor(private readonly appService: AppService). TypeScript emitDecoratorMetadata sozlamasi bilan parametr turini JavaScript'ga yozib qoldiradi — design:paramtypes. Nest uni reflect-metadata bilan o'qiydi. Buni legacy dekoratorlar darsida o'z ko'zingiz bilan ko'rgansiz. Nest build qilgan JS fayldan (biz ishga tushirdik, tsc 6.0.3):

text
AppController = __decorate([
    Controller(),
    __metadata("design:paramtypes", [AppService])
], AppController);

[AppService] — bizning modeldagi [VazifalarXizmati] ning aynan o'zi. Farq shundaki, uni kompilyator yozgan. Shuning uchun Nest kodida interfeys turidagi bog'liqlik avtomatik ishlamaydi: ish vaqtida interfeys yo'q. Unda token kerak — Controller'lar darsida birinchi marta uchratamiz.

5. Narxi: kanon o'lchovlari

5.1 Nest qatlami qancha turadi

Freymvork tekin emas. Nest har so'rovda qo'shimcha ish qiladi: marshrutni topadi, handler'ni o'raydi, javobni o'zi yuboradi. Kanon eng oddiy "salom" serverni beshta usulda yozib, bitta mashinada, bir vaqtda o'lchadi. Grafikda — node:http'ga nisbatan foiz (GET, mediana):

Eng oddiy GET: node:http'ga nisbatan tezlik
  • node:http100 %
  • Fastify 591 %
  • Nest + Fastify88 %
  • Express 559 %
  • Nest + Express50 %

Manba: IlmHamroh kanon o'lchovi, 2026-10-28: Node 24.21.0, @nestjs/core 12.2.0, Windows 11, i5-12500H; req/s medianasi node:http ga bo'lingan; bitta mashina, bir vaqtda, mashina band

Grafikda ikki juftlikka qarang:

  • Express 5 → Nest + Express: 59 dan 50 ga. Nest qatlami Express ustida taxminan 15 % sekinlashtirdi.
  • Fastify 5 → Nest + Fastify: 91 dan 88 ga. Fastify ustida atigi ~4 %.

Ya'ni Nest'ning o'z narxi kichik. Asosiy farq — ichidagi HTTP kutubxonasida. Mutlaq req/s ni yozmadik: mashina boshqa ishlar bilan band edi va raqamlar keng oraliqda o'zgardi. Nisbat esa barqaror.

5.2 vazifalar-api ning narxi

Kanon ko'chishni tugatgach, 27-qismdagi Express versiyasini va Nest versiyasini bir xil sozlama bilan solishtirdi (Postgres rejimi, NODE_ENV=production, bitta mashina):

O'lchov Express Nest
Sovuq start, mediana 2 506 ms 4 757 ms
GET ro'yxat 100 % 67 % (−33 %)
GET /v1/teglar 100 % 72 % (−28 %)
PATCH (baza qulfi) 100 % farqsiz
Prod bog'liqliklar 10 22
Prod o'rnatish hajmi 89 MB 152 MB

Jadvaldan xulosa:

  • Real ilovada farq "salom" serverdagidan katta: 28–33 %. Sabab — Nest'ning qo'shimcha qatlamlari (middleware, guard, pipe zanjiri). Ularni keyingi darslarda qo'shamiz.
  • PATCH'da farq yo'q. U yerda vaqtning asosiy qismini baza oladi. Ko'p real API'lar shunday: tor joy — baza, freymvork emas.
  • Sovuq start ikki baravar uzoq. Server bir marta ishga tushib, soatlab ishlasa — ahamiyatsiz. Har so'rovda yangidan ishga tushadigan muhitda (serverless) esa sezilarli.

Kod hajmi ham o'sdi: src 2 653 qatordan 3 281 qatorga. Dekoratorlar, modul fayllari, klasslar — tartibning narxi.

Diqqat: Bu raqamlar — bitta mashinadagi nisbat. "Nest 33 % sekin" deb hamma loyihaga yoyib bo'lmaydi. Sizning loyihangizda o'zingiz o'lchang (autocannon bilan — Express darslarida ko'rgandik).

6. Qachon Nest, qachon Express

6.1 Tanlov jadvali

Vaziyat Tanlov Nega
Kichik API, 1–2 dasturchi Express yoki Fastify tartib ortiqcha, tezlik yuqori
Katta loyiha, jamoa 5+ Nest hamma bir xil tuzilmada yozadi
Ko'p modul: auth, to'lov, navbat Nest DI ulashni o'zi qiladi
Har so'rovda sovuq start Express, Fastify Nest ikki baravar sekin ko'tariladi
Eng yuqori tezlik kerak Fastify (Nest'siz yoki bilan) adapter tanlovi asosiy farq

Real hayotda yana bir sabab bor: ish bozori. O'zbekistonda va dunyoda ko'p backend vakansiyalarida NestJS talab qilinadi. Katta jamoalar uni aynan tartib uchun tanlaydi. Shuning uchun Express'ni chuqur bilgan holda Nest'ni ham bilish — kuchli kombinatsiya.

6.2 Biz nega ko'chiramiz

vazifalar-api kichik loyiha emas: 25–29-qismlarda auth, integratsiyalar, navbat qo'shildi. Bu qismda uni Nest'ga ko'chirib, ikkalasini halol solishtiramiz: nima yutdik (tartib, DI, test qulayligi), nima yo'qotdik (tezlik, hajm, build qadami). Har darsda: Express'da qanday edi → Nest'da qanday → o'lchov.

Ko'chish usuli — strangler (bo'g'uvchi daraxt naqshi): eski kod ishlab turadi, yangisi yonida o'sadi va qism-qism uning o'rnini egallaydi. Nomi tropik daraxtdan: u boshqa daraxt atrofida o'sib, oxiri uning o'rnini egallaydi.

flowchart LR
  A["Express API ishlaydi"] --> B["Nest skeleti yonida"]
  B --> C["Butun v1 API Nest'da"]
  C --> D["Nest imkoniyatlari"]
  D --> E["Auth va integratsiyalar"]

Strelkalar bo'ylab: keyingi darsda Nest skeleti Express yonida paydo bo'ladi. Undan keyingi to'rt darsda butun API Nest'ga o'tadi. Keyin validatsiya, middleware, config kabi Nest imkoniyatlari keladi. Qism oxirida 28-qismdagi auth va 29-qismdagi integratsiyalar ko'chadi. Har qadamda 25–27-qismdagi testlar o'tib turadi.

6.3 NestJS versiyasi

Kanon NestJS 12.2.0 da qurilgan. 2026-yil 27-oktabr holatida npm'da latest — 12.3.2 edi (o'sha kuni chiqqan), 11-versiya esa legacy tegi ostida faqat tuzatishlar oladi. Kurs qoidasi bo'yicha 7 kundan eski eng yangi barqaror versiya olindi — 12.2.0.

Internetdagi ko'p maqola va Nest hujjatining bir qismi hali 11-versiya haqida. Farqlar asosan loyiha yaratishda (ESM, Vitest, oxlint) — ularni keyingi darsda ko'ramiz. Controller, modul, DI g'oyalari 11 da ham, 12 da ham bir xil.

7. Ko'p uchraydigan xatolar

Noto'g'ri tasavvur Haqiqat
"Nest Express'dan tezroq" Yo'q: Express ustida ~15 %, real ilovada 28–33 % sekinroq (kanon)
"Nest — Express'ning o'rnini bosadi" Ichida Express (yoki Fastify) ishlaydi
"Nest'da new yozish taqiqlangan" Taqiqlanmagan; lekin xizmat va omborni Nest yaratadi
"Nest kodini node fayl.ts bilan ishga tushiraman" Dekorator metama'lumoti uchun build kerak — keyingi dars
"Interfeys bilan DI ishlaydi" Ish vaqtida interfeys yo'q — token kerak

Oxirgisini legacy dekoratorlar darsida ko'rgansiz: interfeys turi design:paramtypes da Object bo'lib qoladi. Nest bunday holatda chalg'ituvchi xato beradi — DI darsida haqiqiy matni bilan ko'ramiz.

8. Mashqlar

Mashqlar kurs/mashqlar/30/01-nest-nima/ da.

1-mashq (oson): bo'shliqlarni to'ldiring

  • Nest ichida sukut bo'yicha ishlaydigan HTTP kutubxonasi —
  • So'rovni qabul qiladigan Nest klassi —
  • Biznes qoidalari yashaydigan klass —
  • Nest provider'ni sukut bo'yicha nechta nusxada yaratadi? —
  • Kanon o'lchovida Nest qatlami Fastify ustida taxminan necha foiz sekinlashtirdi? —
Yechim
  • Express — xohlasa Fastify; ikkalasi platform adapter orqali ulanadi.
  • controller — 25-qismdagi marshrut.ts ning o'rni.
  • xizmat — xizmat.ts ning o'rni; Nest tilida provider.
  • 1 — singleton: butun ilova uchun bitta nusxa.
  • 4 — 91 % dan 88 % ga; Express ustida esa ~15 %.

2-mashq (o'rta): tushunarli xato xabari

Darsdagi konteyner xatosi faqat "Ombor ro'yxatda yo'q" deydi. Kimga kerak bo'lgani noma'lum. ol ni shunday o'zgartiring: bog'liqlik topilmasa, xabar Nest uslubida bo'lsin — VazifalarXizmati ning 0-bog'liqligi (Ombor) ro'yxatda yo'q. Ishora: kerak.map((K, i) => …) ichida this.#royxat.has(K) ni tekshiring (Map); ildiz klassning o'zi yo'q bo'lsa, eski xabar qolsin.

Yechim
js
class Konteyner {
  #royxat = new Map();
  #tayyor = new Map();
  qosh(Klass, kerak = []) {
    this.#royxat.set(Klass, kerak);
  }
  ol(Klass) {
    if (this.#tayyor.has(Klass)) return this.#tayyor.get(Klass);
    const kerak = this.#royxat.get(Klass);
    if (!kerak) throw new Error(`${Klass.name} ro'yxatda yo'q`);
    const argumentlar = kerak.map((K, i) => {
      if (!this.#royxat.has(K)) {
        throw new Error(
          `${Klass.name} ning ${i}-bog'liqligi (${K.name}) ` +
            "ro'yxatda yo'q",
        );
      }
      return this.ol(K);
    });
    const nusxa = new Klass(...argumentlar);
    this.#tayyor.set(Klass, nusxa);
    return nusxa;
  }
}

class Ombor {}
class Log {}
class VazifalarXizmati {
  constructor(log, ombor) { this.log = log; this.ombor = ombor; }
}

const k = new Konteyner();
k.qosh(Log);
k.qosh(VazifalarXizmati, [Log, Ombor]);
try {
  k.ol(VazifalarXizmati);
} catch (e) {
  console.log(e.message);
}
k.qosh(Ombor);
console.log(k.ol(VazifalarXizmati).ombor instanceof Ombor);

Konsolda:

text
VazifalarXizmati ning 1-bog'liqligi (Ombor) ro'yxatda yo'q
true

Log topildi (0-o'rin), Ombor topilmadi (1-o'rin). Nest xabari ham aynan shunday tuzilgan: kimning, nechanchi argumenti, qaysi klass — Please make sure that the argument Ombor at index [1] is available…. Xabarda indeks bo'lgani uchun constructor'dagi qaysi parametr muammo ekani darrov ko'rinadi.

3-mashq (qiyin): aylanma bog'liqlik

A ga B kerak, B ga esa A. Darsdagi konteyner bunday holatda cheksiz chaqiruvga tushadi va RangeError: Maximum call stack size exceeded beradi. Konteynerga "hozir yaratilayotganlar" ro'yxatini qo'shing: klass ikkinchi marta shu ro'yxatda uchrasa, Aylanma bog'liqlik: A → B → A xatosini tashlasin. Ishora: massiv (massivda qidirish) — ol boshida push, nusxa yaratilgach pop; zanjirni join(" → ") bilan yig'ing, pop ni finally ichiga qo'ying.

Yechim
js
class Konteyner {
  #royxat = new Map();
  #tayyor = new Map();
  #yaratilmoqda = [];
  qosh(Klass, kerak = []) {
    this.#royxat.set(Klass, kerak);
  }
  ol(Klass) {
    if (this.#tayyor.has(Klass)) return this.#tayyor.get(Klass);
    if (this.#yaratilmoqda.includes(Klass)) {
      const zanjir = [...this.#yaratilmoqda, Klass]
        .map((K) => K.name);
      throw new Error(`Aylanma bog'liqlik: ${zanjir.join(" → ")}`);
    }
    const kerak = this.#royxat.get(Klass);
    if (!kerak) throw new Error(`${Klass.name} ro'yxatda yo'q`);
    this.#yaratilmoqda.push(Klass);
    try {
      const nusxa = new Klass(...kerak.map((K) => this.ol(K)));
      this.#tayyor.set(Klass, nusxa);
      return nusxa;
    } finally {
      this.#yaratilmoqda.pop();
    }
  }
}

class A { constructor(b) { this.b = b; } }
class B { constructor(a) { this.a = a; } }
class C { constructor(b) { this.b = b; } }

const k = new Konteyner();
k.qosh(A, [B]);
k.qosh(B, [A]);
k.qosh(C, [B]);
for (const K of [A, C]) {
  try {
    k.ol(K);
  } catch (e) {
    console.log(e.message);
  }
}

Konsolda:

text
Aylanma bog'liqlik: A → B → A
Aylanma bog'liqlik: C → B → A → B

finally muhim: xato bo'lsa ham pop bajariladi va ro'yxat keyingi ol uchun toza qoladi. Ikkinchi qatorda C aylanmaning o'zida emas, lekin unga yetib boradi — zanjir buni ko'rsatadi. Nest ham aylanma bog'liqlikni aniqlaydi va o'z xatosini beradi. Uni chetlab o'tish usullari (forwardRef) — Circular dependency darsida.

9. Loyiha qadami: Nest paketlarini o'rnatish

Ko'chishning birinchi qadami — paketlar. Express kodi hech o'zgarmaydi va ishlashda davom etadi. vazifalar-api papkasida (C:/Users/…/vazifalar-api):

bash
npm i --save-exact @nestjs/common@12.2.0 \
  @nestjs/core@12.2.0 @nestjs/platform-express@12.2.0 \
  reflect-metadata@0.2.2 rxjs@7.8.2
npm i -D --save-exact @nestjs/cli@12.0.9 \
  @nestjs/schematics@12.0.9 @nestjs/testing@12.2.0 \
  vitest@5.0.5 vite@8.3.4
npm pkg set version=2.0.0-alfa.0

Har paket nima uchun:

Paket Vazifasi
@nestjs/common dekoratorlar: @Controller, @Get, @Module
@nestjs/core yadro: DI konteyner, NestFactory
@nestjs/platform-express Express adapteri
reflect-metadata design:paramtypes ni o'qish
rxjs Nest ichida ishlatiladi (interceptor'lar)

Dev paketlar: @nestjs/cli — nest buyrug'i (build, generatsiya), @nestjs/schematics — CLI shablonlari, @nestjs/testing — Nest test moduli, vitest va vite — test vositasi. Hammasi keyingi darsda ishga tushadi.

rxjs — kuzatiladigan oqimlar kutubxonasi. Nest uni interceptor'larda ishlatadi; Interceptor'lar va RxJS darsigacha unga tegmaymiz.

Versiya 2.0.0-alfa.0: Nest'ga o'tish — tashqi API o'zgarmasa ham ichki buzuvchi o'zgarish (build qadami paydo bo'ladi). Shuning uchun asosiy raqam 2 ga chiqdi. -alfa.0 — hali tayyor emas degani (semver darsi).

Kanon natijasi: prod bog'liqliklar 10 tadan 15 taga chiqdi (Nest 5 ta). Tekshiring:

bash
npm ls --depth=0 @nestjs/core rxjs reflect-metadata
npm test

npm test hali eski 27-qism testlarini yurgizadi — natija o'zgarmasligi kerak. Hali commit qilmang: skelet keyingi darsda qo'shiladi va commit o'sha yerda.

10. Real ishda

  • Qayerda uchraydi: banklar, fintech, e-commerce backend'larida — ko'p modulli, jamoaviy loyihalarda. Express esa kichik xizmatlar, prototiplar va serverless funksiyalarda.
  • Intervyu savollari: "NestJS Express'dan nimasi bilan farq qiladi?", "Dependency injection nima va nega kerak?", "Nest provider'i sukut bo'yicha qanday scope'da?" (javob: singleton).
  • Jamoada: Nest loyihasiga yangi dasturchi bir kunda kirishadi — tuzilma tanish. Bu Nest tanlashning eng ko'p aytiladigan sababi.
  • Kod review'da: "bu xizmatni nega new bilan yaratdingiz?" — Nest loyihasida eng ko'p uchraydigan izohlardan biri.

Xulosa

  • NestJS — Express (sukut) yoki Fastify ustidagi fikrli freymvork; HTTP'ni ular, arxitekturani Nest beradi.
  • Uch g'isht: modul, controller, xizmat (provider). Dekoratorlar ularni Nest'ga tanitadi.
  • DI konteyner bog'liqliklarni o'zi yaratadi va ulaydi; provider sukut bo'yicha singleton.
  • Narxi bor: kanon o'lchovida Express ustida ~15 %, real ilovada 28–33 % sekinroq, sovuq start ikki baravar.
  • Kichik API — Express/Fastify; katta jamoa va ko'p modul — Nest.
  • vazifalar-api strangler usulida ko'chadi; birinchi qadam — paketlar.

Keyingi dars: Nest CLI va loyiha tuzilmasi — nest new bilan loyiha yaratamiz, har faylni ko'rib chiqamiz va vazifalar-api ga Nest skeletini qo'shamiz.

Manbalar

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
NestJS nima va nega: Express ustidagi tartibli arxitektura — IlmHamroh