WisarWisar
Dasturlash kitobi/8-QISM — NestJS24 daqiqa

8.1-bob: NestJS kirish — arxitektura, modules, controllers, providers

8-QISM — NestJS (chuqur) · 1-mavzu


1. Kirish va motivatsiya

TypeScript (7), Node.js backend (5), DB (6) ni chuqur bildik. Endi ularni birlashtiruvchi, zamonaviy, korporativ darajadagi framework — NestJS ni o'rganamiz. Bu — sizning backend kareyrangizning eng muhim qismi: O'zbekistonda va dunyoda jiddiy Node.js loyihalari (korxonalar, banklar, SaaS) ko'pincha NestJS'da quriladi. Express 5.6-bob — minimalist (har narsani o'zingiz tashkillaysiz); NestJS — strukturali (arxitekturani majburlaydi) — katta, jamoaviy, uzoq muddatli loyihalar uchun.

NestJS — 2017-yilda Kamil Myśliwiec tomonidan yaratilgan, TypeScript bilan qurilgan, Angular'dan ilhomlangan Node.js framework. Asosiy maqsadi: Express'ning erkinligi (va tartibsizligi) o'rniga — opinionated (bir xil, to'g'ri yo'l), modular, testlanadigan, masshtablanadigan arxitektura. U OOP (2.5-JS), FP (2.15-JS), va FRP (RxJS) elementlarini birlashtiradi. Eng muhimi: dependency injection (DI — 8.2) — bog'liqliklarni avtomatik boshqarish — toza, testlanadigan kodning asosi.

Bu bob — alohida e'tibor bilan (sizning eng muhim joyingiz): NestJS'ning falsafasi (nega bor, qaysi muammoni hal qiladi), ichki ishlash (IoC konteyner, bootstrap, lifecycle, request lifecycle — promptda yo'q, lekin zarur), CLI, va asosiy uchlik — module / controller / provider — chuqur. Bu — butun 8-QISM (DI, DB, guards, auth, microservices...) ning poydevori. NestJS'ni tushunish = uning arxitektura falsafasini tushunish (sintaksis emas).

O'xshatish (NestJS vs Express): Express — bo'sh yer + g'isht (xohlagan uyni qurasiz — erkin, lekin har kim har xil quradi, tartibsiz bo'lishi mumkin). NestJS — tayyor konstruktor (LEGO) + qoidalar (qismlar aniq — modul, controller, service; ular qanday ulanishi belgilangan). Erkinlik kamroq, lekin natija izchil, mustahkam, jamoa tushunadigan. Katta bino (korporativ ilova) uchun — konstruktor afzal (har kim bir xil quradi).

Nega muhim?

  • Kareyra asosi — jiddiy Node.js ish o'rinlari NestJS talab qiladi.
  • Arxitektura — katta/jamoaviy loyiha uchun struktura (Express'da yo'q).
  • DI + testlanadigan — toza, mustahkam, sinaladigan kod.
  • Hammasi birga — TS + DB + auth + microservices + GraphQL — bir framework.

2. Nazariya — chuqur tushuntirish

2.1. NestJS nima va tarixi (falsafa)

NestJS — TypeScript-first, Angular-uslubidagi Node.js backend framework:

text
  Tarixi:
  - 2017: Kamil Myśliwiec yaratdi
  - Maqsad: Angular arxitektura naqshlarini backend'ga olib kelish
  - "Progressive Node.js framework" (rivojlanuvchi)

  Falsafasi (4 ustun):
  1. Consistency  — bitta, to'g'ri yo'l (opinionated)
  2. Scalability  — modullar bilan o'sish (jamoa, kod)
  3. Testability  — DI + Jest (sinaladigan)
  4. Extensibility — plugin tizimi (ORM, GraphQL, microservices)

NestJS falsafasi: Express "qanday istasangiz" (erkin, lekin har loyiha har xil). NestJS — "to'g'ri yo'l" (opinionated): arxitektura belgilangan, har kim bir xil quradi. Bu — katta, jamoaviy loyihada bebaho (yangi dasturchi tez tushunadi, kod izchil).

2.2. NestJS Express ustida (adapter)

Muhim fakt (promptda yo'q): NestJS — Express ustida ishlaydi (default):

text
  NestJS (yuqori daraja — arxitektura, DI, dekorator)
        │
        ▼ (adapter)
  Express (yoki Fastify) — HTTP server 5.6-bob
        │
        ▼
  Node.js HTTP 5.5-bob

   NestJS Express'ni ALMASHTIRMAYDI — uning USTIDA (abstraksiya)
   Fastify adapter ham bor (tezroq — platformFastify)

NestJS Express'ni o'rab oladi (default adapter): siz NestJS dekoratorlari bilan yozasiz, ostida Express ishlaydi. Demak, Express bilimi (5.6 — middleware, req/res) — NestJS'da ham kerak. Fastify adapter (tezroq) ham mavjud. NestJS — "platforma-agnostik" (Express/Fastify almashtirsa bo'ladi).

Fastify adapter'ga o'tish — bootstrap'da bitta o'zgarish (main.ts):

ts
import { NestFactory } from "@nestjs/core";
import {
  FastifyAdapter,
  NestFastifyApplication,
} from "@nestjs/platform-fastify";       // npm i @nestjs/platform-fastify
import { AppModule } from "./app.module";

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),                // Express o'rniga Fastify
  );
  await app.listen(3000, "0.0.0.0");    // Fastify — host talab qiladi
}
bootstrap();

Express vs Fastify adapter: default — Express (@nestjs/platform-express, keng ekotizim, ko'p middleware — 5.6). Fastify (@nestjs/platform-fastify) — sezilarli tezroq (yuqori throughput, past overhead), lekin ekotizimi kichikroq. Controller/service kodingiz bir xil qoladi (dekoratorlar o'zgarmaydi) — faqat main.ts va xom @Req()/@Res() turlari (FastifyRequest/FastifyReply) farq qiladi. Shu bois xom req/resdan qochish (2.7.1) — adapter'dan mustaqil kod beradi.

2.3. Angular ilhomi (mental model)

text
  Angular (frontend)          NestJS (backend) — bir xil g'oya:
  @Component                  @Controller (so'rovlarni qabul qiladi)
  @Injectable (service)      @Injectable (provider — biznes logika)
  @NgModule                  @Module (guruhlash)
  Dependency Injection       Dependency Injection 8.2-bob
  Dekorator + DI             Dekorator + DI

   Angular bilsangiz, NestJS mental modeli tanish

Angular mental modeli: NestJS arxitekturasi Angular'dan olingan (dekorator, DI, modul). Bu — frontend (Angular) va backend (NestJS) bir xil falsafada (full-stack izchillik). Angular bilmasangiz ham mayli — bu yerda boshidan o'rganamiz.

2.4. NestJS CLI (loyiha vositasi)

NestJS CLI — loyiha yaratish, komponent generatsiya, build:

bash
npm install -g @nestjs/cli            # CLI o'rnatish (global)

nest new loyiha-nomi                  # yangi loyiha (to'liq tuzilma)
nest generate module users            # modul (yoki: nest g module users)
nest g controller users               # controller
nest g service users                  # service (provider)
nest g resource users                 # TO'LIQ CRUD (module+controller+service+DTO+entity)

npm run start:dev                     # dev (watch — o'zgarishni kuzatadi)
npm run build                         # production build

nest g resource — eng kuchli buyruq (promptda yo'q): bitta buyruqda to'liq CRUD resurs (module + controller + service + DTO + entity + test) generatsiya qiladi (REST/GraphQL/microservice tanlash bilan). CLI — NestJS DX (developer experience) ning asosi: qo'lda fayl yaratmaysiz, generatsiya qilasiz (izchil, tez).

2.5. Loyiha tuzilmasi (nest new)

text
  loyiha/
  ├── src/
  │   ├── main.ts                — entry (bootstrap — 2.10)
  │   ├── app.module.ts          — root modul 2.6-bob
  │   ├── app.controller.ts      — controller 2.7-bob
  │   ├── app.service.ts         — service/provider 2.8-bob
  │   └── users/                 — feature modul (har resurs alohida)
  │       ├── users.module.ts
  │       ├── users.controller.ts
  │       ├── users.service.ts
  │       ├── dto/               — DTO 8.5-bob
  │       └── entities/          — entity 8.3-bob
  ├── test/                      — e2e testlar 8.11-bob
  ├── nest-cli.json              — CLI sozlama
  └── tsconfig.json              — TS (7.1, dekorator yoqilgan — 7.6)

Feature-based tuzilma: har resurs (users, products, orders) — o'z moduli (module + controller + service + dto). Bu — modularlik 2.6-bob: har xususiyat mustaqil, kengaytiriladigan. Express'da bu — qo'lda; NestJS — majburlaydi (struktura).

2.6. Module (modul) — guruhlash birligi

Module — bog'liq funksionallikni guruhlovchi birlik (@Module — docs):

ts
import { Module } from "@nestjs/common";
import { UsersController } from "./users.controller";
import { UsersService } from "./users.service";

@Module({
  imports: [],                  // boshqa modullar (bog'liqliklar)
  controllers: [UsersController], // bu modul controller'lari
  providers: [UsersService],    // bu modul provider'lari (servicelar)
  exports: [UsersService],      // boshqa modullarga ulashish
})
export class UsersModule {}

Module — "qadoq": bog'liq narsalarni (controller + service + ...) bir joyga to'playdi. Har ilovada kamida root module (AppModule). Modullar daraxt hosil qiladi (root feature modullar). exports — modul ichidagini boshqasiga ulashish 2.13-bob. Bu — masshtablanadigan arxitektura asosi.

2.7. Controller — so'rovlarni qabul qilish

Controller — HTTP so'rovlarni qabul qilib, javob qaytaradi (@Controller — docs):

ts
import { Controller, Get, Post, Body, Param } from "@nestjs/common";
import { UsersService } from "./users.service";

@Controller("users")            // route prefiks: /users
export class UsersController {
  constructor(private usersService: UsersService) {}   // DI — service inject (8.2)

  @Get()                        // GET /users
  hammasi() {
    return this.usersService.hammasi();
  }

  @Get(":id")                   // GET /users/:id
  bitta(@Param("id") id: string) {
    return this.usersService.bitta(+id);
  }

  @Post()                       // POST /users
  yarat(@Body() data: CreateUserDto) {
    return this.usersService.yarat(data);
  }
}

Controller — "yo'l boshqaruvchisi": so'rovni qabul qiladi (@Get, @Post — 7.6 dekorator), ma'lumotni oladi (@Param, @Body), va service'ga uzatadi (biznes logikani o'zi qilmaydi!). Controller — yupqa bo'lishi kerak (faqat HTTP; mantiq — service'da — 9: SRP). Bu — Express route handler'ning 5.6-bob tashkillangan versiyasi.

2.7.1. Route metod va parametr dekoratorlari (to'liq)

Route metod dekoratorlari — har HTTP metod uchun 5.7-bob:

text
  @Get()    — o'qish (GET)
  @Post()   — yaratish (POST)
  @Put()    — to'liq almashtirish (PUT)
  @Patch()  — qisman yangilash (PATCH)
  @Delete() — o'chirish (DELETE)
  @All()    — barcha metod;  @Options()/@Head() — kamroq ishlatiladi

Parametr dekoratorlari — so'rovdan ma'lumot olish (Express req o'rniga — 5.6):

ts
import {
  Controller, Get, Post, Put,
  Param, Query, Body, Headers, Req, Res, Ip, HostParam,
} from "@nestjs/common";
import { Request, Response } from "express";

@Controller("users")
export class UsersController {
  @Get(":id")
  bitta(
    @Param("id") id: string,              // yo'l parametri: /users/42  "42"
    @Query("full") full: string,          // query: ?full=true  "true"
    @Headers("authorization") auth: string, // sarlavha (5.7)
    @Ip() ip: string,                     // mijoz IP manzili
  ) {
    return { id, full, auth, ip };
  }

  @Put()
  almashtir(@Body() dto: CreateUserDto) {  // butun tanani (JSON) oladi
    return dto;
  }

  // @Param() — barchasini obyekt sifatida;  @Query() — barcha query obyekt
  @Get()
  filtr(@Query() query: Record<string, string>) {
    return query;                          // { page: "1", sort: "name" }
  }
}

Parametr dekoratorlari — Express reqning bo'linishi: Express'da req.params, req.query, req.body, req.headers 5.6-bob — hammasi req obyektidan. NestJS bularni alohida dekoratorga ajratadi (@Param, @Query, @Body, @Headers, @Ip) — aniq, testlanadigan, deklarativ. Argument bersangiz (@Param("id")) — bitta maydon; bermasangiz (@Param()) — butun obyekt.

@Req() va @Res() — ehtiyot bo'ling: @Req() req: Request — xom Express so'rov obyektini beradi (kamdan-kam kerak — dekoratorlar yetarli). @Res() res: Response — xom javob obyekti: agar ishlatsangiz, NestJS'ning avtomatik javob (return qilingan qiymatni JSON'ga aylantirish) o'chadi — o'zingiz res.json() chaqirishingiz kerak. Bu — NestJS naqshini buzadi; imkon qadar @Res()dan qoching (return yetarli). Zarur bo'lsa — @Res({ passthrough: true }) (NestJS javobni baribir boshqaradi).

2.8. Provider (service) — biznes logika

Provider (odatda service) — biznes logikani saqlaydi (@Injectable — docs):

ts
import { Injectable } from "@nestjs/common";

@Injectable()                   // bu class — provider (DI uchun)
export class UsersService {
  private users = [];           // (DB — 8.3)

  hammasi() {
    return this.users;          // biznes logika
  }
  yarat(data: CreateUserDto) {
    const user = { id: Date.now(), ...data };
    this.users.push(user);
    return user;
  }
}

Provider — "miya": asosiy ish (biznes logika, DB, hisoblash) — provider'da. @Injectable() — "bu class DI orqali boshqalarga berilishi mumkin" 8.2-bob. Provider'lar bir-biriga inject qilinadi (service repository ...). Controller (HTTP) Service (biznes) Repository (DB) — qatlamlar (9).

2.9. Module / Controller / Provider — birga (uchlik)

text
  So'rov oqimi (NestJS uchlik):
  HTTP so'rov  CONTROLLER (qabul, /users)
                   │ usersService.hammasi()  (DI — 8.2)
                   ▼
              PROVIDER/SERVICE (biznes logika)
                   │ DB so'rov 8.3-bob
                   ▼
              javob  CONTROLLER  HTTP javob

  MODULE — bularni guruhlaydi (UsersModule: controller + service)

Uchlikning vazifasi: Controller (HTTP — yupqa); Service (biznes — qalin); Module (guruhlash). Aniq mas'uliyat ajratish (9: separation of concerns). Bu — NestJS'ning yuragi. Har feature shu uchlikdan iborat.

2.10. Bootstrap (ilova ishga tushishi)

Bootstrap — NestJS ilovasini ishga tushirish jarayoni (main.ts):

ts
// main.ts
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";

async function bootstrap() {
  const app = await NestFactory.create(AppModule);   // ilovani yaratish
  app.setGlobalPrefix("api");                          // /api prefiks
  app.useGlobalPipes(new ValidationPipe());            // global pipe (8.5)
  await app.listen(3000);                              // tinglash
}
bootstrap();
text
  Bootstrap ichki bosqichlari (promptda yo'q — muhim):
  1. NestFactory.create(AppModule) — root moduldan boshlash
  2. Module discovery — barcha modullarni skanerlash (imports daraxti)
  3. Dependency resolution — har provider instansiyalanadi (DI — 8.2)
  4. Dynamic modules (forRoot/register) — sozlanadi
  5. Lifecycle hooks (onModuleInit, onApplicationBootstrap — 2.15)
  6. app.listen — HTTP server (Express — 2.2) tinglaydi

Bootstrap — boshlanish: NestFactory.create(AppModule) — root moduldan butun modul grafini quradi, har bog'liqlikni hal qiladi (DI konteyner — 2.11), va server tinglaydi. Bu — Express'dagi app.listen() ning kengaytirilgan, tashkillangan versiyasi.

2.11. IoC konteyner va DI (kirish — 8.2 chuqur)

IoC (Inversion of Control) konteyner — NestJS'ning yuragi: bog'liqliklarni avtomatik yaratib, ulaydi:

text
  An'anaviy (qo'lda):
  const db = new Database();
  const service = new UserService(db);     // O'ZINGIZ yaratasiz/ulaysiz
  const controller = new UserController(service);

  NestJS (IoC — avtomatik):
  constructor(private service: UserService) {}   // FAQAT so'raysiz
   NestJS UserService'ni (va uning bog'liqliklarini) O'ZI yaratib beradi

  "Inversion of Control" — yaratish nazoratini SIZ emas, KONTEYNER qiladi

IoC konteyner 2.11-bob — DI'ning 8.2-bob asosi. Siz bog'liqlikni so'raysiz (constructor'da), NestJS uni yaratib beradi (tur bo'yicha — TS + reflect-metadata — 7.6: 2.10). Bu — "nazoratning teskari aylanishi" (yaratishni o'zingiz emas, konteyner qiladi). Toza, testlanadigan kod (8.2'da chuqur).

2.12. Request lifecycle (so'rov yo'li — promptda yo'q, muhim)

NestJS'da har so'rov belgilangan tartibda qatlamlardan o'tadi:

text
  HTTP so'rov 
  1. Middleware (5.6 — global/modul)
  2. Guards (auth/RBAC — 8.7)
  3. Interceptors (oldin — log/transform — 8.7)
  4. Pipes (validatsiya/transform — 8.5)
  5. CONTROLLER handler (route metod)
        Service (biznes logika)
  6. Interceptors (keyin — javobni o'zgartirish)
  7. Exception filters (xato bo'lsa — 8.7)
   HTTP javob

Request lifecycle — NestJS'ni tushunishning kaliti (promptda yo'q): har so'rov shu tartibda o'tadi (middleware guard interceptor pipe handler interceptor filter). Bu tartibni bilish — guard, pipe, interceptor 8.7-bob qayerda ishlashini tushunishga yordam beradi. Express'da bu — faqat middleware zanjir; NestJS — boy, tartibli.

2.13. Module turlari (feature, shared, global, dynamic)

text
  Feature module — bitta xususiyat (UsersModule — 2.6)
  Shared module  — qayta ishlatiladigan (DatabaseModule — exports bilan)
  Global module  — hamma joyda (@Global — har joyga import qilmasdan)
  Dynamic module — sozlanadigan (forRoot/register — ConfigModule — 8.14)
ts
// Dynamic module (sozlanadigan — 8.14)
@Module({})
export class ConfigModule {
  static forRoot(options): DynamicModule {   // sozlash bilan
    return { module: ConfigModule, providers: [...], global: true };
  }
}
// Ishlatish: ConfigModule.forRoot({ ... })

Module turlari: feature (har xususiyat); shared (ulashiladigan — exports); global (@Global — DB, config); dynamic (forRoot() — sozlanadigan — 8.14). Dynamic module — NestJS ekotizimining asosi (TypeOrmModule.forRoot, JwtModule.register — 8.3, 8.9).

2.14. Provider scope (lifetime — promptda yo'q)

text
  DEFAULT (Singleton) — bitta instansiya, butun ilova (eng ko'p — tez)
  REQUEST — har so'rovga yangi instansiya (so'rovga xos ma'lumot)
  TRANSIENT — har inject'ga yangi instansiya

  @Injectable({ scope: Scope.REQUEST })
  export class RequestService {}

Provider scope: default — singleton (bir instansiya — tez, ko'p ishlatiladi). REQUEST — har so'rovga yangi (so'rovga xos kontekst — masalan request logger — 5.12). TRANSIENT — har inject'ga yangi. Ko'p holatda singleton; REQUEST — ehtiyot (sekinroq). Bu — DI'ning nozik tomoni.

2.15. Lifecycle hooks (hayot sikli — promptda yo'q)

NestJS provider/module'larda lifecycle hook'lar:

ts
import { OnModuleInit, OnModuleDestroy } from "@nestjs/common";

@Injectable()
export class UsersService implements OnModuleInit, OnModuleDestroy {
  onModuleInit() {                // modul tayyor bo'lganda (DB ulanish — 8.3)
    console.log("UsersService tayyor");
  }
  onModuleDestroy() {             // ilova to'xtaganda (tozalash — 5.10)
    console.log("UsersService tozalanmoqda");
  }
}

Lifecycle hooks: onModuleInit (modul tayyor — DB ulanish, kesh isitish), onApplicationBootstrap (hamma modul tayyor), onModuleDestroy/beforeApplicationShutdown (graceful shutdown — 5.10). Resurslarni boshqarish (ulanish, navbat — 5.22) uchun. enableShutdownHooks() kerak (shutdown uchun).

2.16. NestJS vs Express (qachon qaysi biri)

text
  ┌──────────────┬──────────────────┬──────────────────┐
  │              │ Express 5.6-bob    │ NestJS           │
  ├──────────────┼──────────────────┼──────────────────┤
  │ Falsafa      │ minimalist/erkin │ opinionated/struktura│
  │ Arxitektura  │ qo'lda tashkil   │ majburiy (modul) │
  │ TypeScript   │ qo'shimcha       │ tug'ma (native)  │
  │ DI           │ yo'q (qo'lda)    │ tug'ma (IoC)     │
  │ O'rganish    │ oson             │ qiyinroq         │
  │ Kichik loyiha│  tez           │ ortiqcha         │
  │ Katta/jamoa  │ tartibsizlik xavfi│  izchil       │
  └──────────────┴──────────────────┴──────────────────┘

Tanlov: kichik/tez loyiha, MVP — Express (yengil). Katta, jamoaviy, uzoq muddatli, korporativ — NestJS (struktura, DI, testlanadigan). Sizning kareyrangiz uchun — NestJS (jiddiy loyihalar). Express bilimi 5.6-bob — NestJS asosi (ostida ishlaydi — 2.2).

2.17. NestJS ekotizimi (rasmiy modullar)

text
  @nestjs/config       — env/config 8.14-bob
  @nestjs/typeorm      — TypeORM 8.3-bob; @nestjs/mongoose — Mongoose 8.13-bob
  @nestjs/jwt, passport — auth 8.9-bob
  @nestjs/swagger      — API hujjat 8.8-bob
  @nestjs/cache-manager — Redis kesh 8.15-bob
  @nestjs/bullmq       — navbat 8.22-bob; @nestjs/schedule — cron
  @nestjs/microservices — mikroservis 8.18-bob; @nestjs/graphql 8.19-bob
  @nestjs/websockets   — WebSocket gateway 8.21-bob
  @nestjs/testing      — test (8.11)

NestJS ekotizimi — har ehtiyojga rasmiy, integratsiyalashgan modul. Express'da har biri alohida paket (qo'lda ulash); NestJS'da — bir xil naqsh (forRoot/register — 2.13), DI bilan integratsiya. Bu — butun 8-QISM mavzulari (har biri alohida bobda).

2.18. Toza kod va arxitektura (9 ko'prik)

text
  NestJS arxitektura SOLID/Clean'ni RAG'BATLANTIRADI (9):
  - SRP: controller (HTTP), service (biznes), repository (DB) — ajratilgan
  - DIP: interface + DI 8.2-bob — bog'liqlikni teskari aylantirish
  - Modularlik: feature modullar (kengaytiriladigan)
  - Testlanadigan: DI  mock oson 8.11-bob

   NestJS "to'g'ri arxitektura"ni qiyin emas, OSON qiladi

NestJS — toza arxitektura (9: SOLID, Clean Architecture) ni tabiiy qiladi: qatlamlar ajratilgan, DI bilan bog'langan, modular. Express'da bu — intizom talab qiladi (o'zingiz); NestJS — struktura beradi. Bu — sifatli, uzoq muddatli kod.

2.19. Best practices (NestJS kirish)

text
   CLI bilan generatsiya (nest g resource — izchil — 2.4)
   Controller yupqa (faqat HTTP); service qalin (biznes — 2.7, 2.8)
   Feature-based modullar (har resurs — modul — 2.5)
   Default singleton scope (REQUEST ehtiyot — 2.14)
   Global pipe/filter (main.ts — 2.10, 8.5)
   exports bilan ulashish (shared modul — 2.13)
   Lifecycle hooks (resurs boshqaruvi — 2.15)
   Request lifecycle'ni tushun (guard/pipe joyi — 2.12)

3. Sintaksis — tez ma'lumotnoma

ts
// Module (2.6)
@Module({ imports: [], controllers: [X], providers: [Y], exports: [Y] })
export class XModule {}

// Controller (2.7)
@Controller("users")
export class UsersController {
  constructor(private service: UsersService) {}   // DI (8.2)
  @Get() hammasi() {}  @Get(":id") bitta(@Param("id") id) {}  @Post() yarat(@Body() dto) {}
}

// Provider (2.8)
@Injectable() export class UsersService {}

// Bootstrap 2.10-bob: NestFactory.create(AppModule)  app.listen(3000)
bash
nest new loyiha    nest g resource users    npm run start:dev

4. Batafsil kod namunalari

Misol 1 — main.ts (bootstrap — 2.10)

ts
// main.ts — ilova kirish nuqtasi
import { NestFactory } from "@nestjs/core";
import { ValidationPipe } from "@nestjs/common";
import { AppModule } from "./app.module";

async function bootstrap() {
  const app = await NestFactory.create(AppModule);   // root moduldan (2.10)

  app.setGlobalPrefix("api");                          // barcha route: /api/...
  app.useGlobalPipes(new ValidationPipe({             // global validatsiya (8.5)
    whitelist: true,                                   // DTO'da yo'q maydonni o'chir
    transform: true,                                   // tur'ga aylantirish
  }));
  app.enableCors();                                    // CORS (5.20)
  app.enableShutdownHooks();                           // lifecycle (2.15)

  await app.listen(3000);
  console.log("Server: http://localhost:3000/api");
}
bootstrap();

Misol 2 — Root module (AppModule — 2.6)

ts
// app.module.ts — ildiz modul
import { Module } from "@nestjs/common";
import { ConfigModule } from "@nestjs/config";        // (8.14)
import { UsersModule } from "./users/users.module";
import { ProductsModule } from "./products/products.module";

@Module({
  imports: [
    ConfigModule.forRoot({ isGlobal: true }),          // global config (8.14, 2.13)
    UsersModule,                                        // feature modullar (2.5)
    ProductsModule,
  ],
})
export class AppModule {}
// Root modul — barcha feature modullarni birlashtiradi (modul daraxti — 2.6)

Misol 3 — Feature module (UsersModule — 2.6, 2.9)

ts
// users/users.module.ts
import { Module } from "@nestjs/common";
import { UsersController } from "./users.controller";
import { UsersService } from "./users.service";

@Module({
  controllers: [UsersController],    // HTTP qatlam (2.7)
  providers: [UsersService],         // biznes qatlam (2.8)
  exports: [UsersService],           // boshqa modullar uchun (2.13)
})
export class UsersModule {}

Misol 4 — Controller (to'liq CRUD — 2.7)

ts
// users/users.controller.ts
import {
  Controller, Get, Post, Patch, Delete, Body, Param, Query, HttpCode, HttpStatus,
} from "@nestjs/common";
import { UsersService } from "./users.service";
import { CreateUserDto, UpdateUserDto } from "./dto";   // (8.5)

@Controller("users")                 // /api/users (global prefiks — 2.10)
export class UsersController {
  constructor(private readonly usersService: UsersService) {}   // DI (8.2)

  @Get()                             // GET /api/users
  hammasi(@Query("page") page = "1") {
    return this.usersService.hammasi(+page);
  }

  @Get(":id")                        // GET /api/users/:id
  bitta(@Param("id") id: string) {
    return this.usersService.bitta(+id);   // NotFound bo'lsa — 404 (8.7)
  }

  @Post()                            // POST /api/users
  @HttpCode(HttpStatus.CREATED)      // 201 (5.7)
  yarat(@Body() dto: CreateUserDto) {
    return this.usersService.yarat(dto);
  }

  @Patch(":id")                      // PATCH /api/users/:id
  yangila(@Param("id") id: string, @Body() dto: UpdateUserDto) {
    return this.usersService.yangila(+id, dto);
  }

  @Delete(":id")                     // DELETE /api/users/:id
  @HttpCode(HttpStatus.NO_CONTENT)   // 204
  ochir(@Param("id") id: string) {
    return this.usersService.ochir(+id);
  }
}
// Controller — yupqa: faqat HTTP, service'ga uzatadi (2.7)

Misol 5 — Service (biznes logika — 2.8)

ts
// users/users.service.ts
import { Injectable, NotFoundException } from "@nestjs/common";
import { CreateUserDto, UpdateUserDto } from "./dto";

@Injectable()                        // provider (2.8)
export class UsersService {
  private users: any[] = [];         // (DB — 8.3)
  private idHisob = 1;

  hammasi(page: number) {
    return this.users.slice((page - 1) * 20, page * 20);   // sahifalash (5.7)
  }

  bitta(id: number) {
    const user = this.users.find((u) => u.id === id);
    if (!user) throw new NotFoundException(`${id}-foydalanuvchi topilmadi`);   // 404 (8.7)
    return user;
  }

  yarat(dto: CreateUserDto) {
    const user = { id: this.idHisob++, ...dto };
    this.users.push(user);
    return user;
  }

  yangila(id: number, dto: UpdateUserDto) {
    const user = this.bitta(id);     // topilmasa — 404 (qayta ishlatish)
    Object.assign(user, dto);
    return user;
  }

  ochir(id: number) {
    const user = this.bitta(id);
    this.users = this.users.filter((u) => u.id !== id);
  }
}
// NotFoundException — NestJS built-in exception 8.7-bob  avtomatik 404 JSON

Misol 6 — Built-in exceptions (xato — 8.7 kirish)

ts
import {
  NotFoundException,      // 404
  BadRequestException,    // 400
  UnauthorizedException,  // 401
  ForbiddenException,     // 403
  ConflictException,      // 409
} from "@nestjs/common";

@Injectable()
export class UsersService {
  yarat(dto: CreateUserDto) {
    const mavjud = this.users.find((u) => u.email === dto.email);
    if (mavjud) throw new ConflictException("Email band");   // 409 (5.7)
    // ...
  }
}
// NestJS xatoni AVTOMATIK to'g'ri HTTP javobga aylantiradi (5.10 — exception filter)

Misol 7 — Service'lar bir-biriga inject (DI — 2.11, 8.2)

ts
// Bir service boshqasini ishlatadi (DI — 2.11)
@Injectable()
export class EmailService {                          // (5.19)
  yubor(to: string, matn: string) { /* ... */ }
}

@Injectable()
export class UsersService {
  constructor(private emailService: EmailService) {} // DI — NestJS o'zi beradi (2.11)

  async yarat(dto: CreateUserDto) {
    const user = { id: 1, ...dto };
    await this.emailService.yubor(user.email, "Xush kelibsiz!");   // boshqa service
    return user;
  }
}
// EmailService UsersModule providers'ida yoki import qilingan modulda bo'lishi kerak (2.13)

Misol 8 — Lifecycle hooks (2.15)

ts
import { Injectable, OnModuleInit, OnModuleDestroy } from "@nestjs/common";

@Injectable()
export class DatabaseService implements OnModuleInit, OnModuleDestroy {
  async onModuleInit() {
    await this.ulanish();            // DB ulanish (modul tayyor bo'lganda — 8.3)
    console.log(" DB ulandi");
  }
  async onModuleDestroy() {
    await this.uzish();              // graceful shutdown (5.10)
    console.log("DB uzildi");
  }
  private async ulanish() { /* ... */ }
  private async uzish() { /* ... */ }
}

Misol 9 — Global module (2.13)

ts
// database/database.module.ts — global (har joyda — 2.13)
import { Module, Global } from "@nestjs/common";
import { DatabaseService } from "./database.service";

@Global()                            // GLOBAL — har modulga import qilmasdan
@Module({
  providers: [DatabaseService],
  exports: [DatabaseService],        // ulashish
})
export class DatabaseModule {}
// Endi DatabaseService har joyda inject qilinadi (import shart emas — 2.13)

Misol 10 — REST'dan service ishlatish (qatlamlar — 2.9)

ts
// To'liq oqim: Controller  Service  (boshqa Service)
@Controller("orders")
export class OrdersController {
  constructor(private ordersService: OrdersService) {}   // DI

  @Post()
  yarat(@Body() dto: CreateOrderDto) {
    return this.ordersService.yarat(dto);   // service'ga uzatadi (controller yupqa)
  }
}

@Injectable()
export class OrdersService {
  constructor(
    private usersService: UsersService,      // DI — boshqa service (2.11)
    private emailService: EmailService,      // DI
  ) {}

  async yarat(dto: CreateOrderDto) {
    const user = this.usersService.bitta(dto.userId);   // foydalanuvchi tekshir
    const order = { id: 1, ...dto };          // (DB — 8.3)
    await this.emailService.yubor(user.email, `Buyurtma #${order.id}`);   // (5.19)
    return order;
  }
}
// Qatlamlar: Controller (HTTP)  Service (biznes)  boshqa Service'lar (2.9, 9)

Misol 11 — async route va Promise (2.7)

ts
@Controller("users")
export class UsersController {
  constructor(private usersService: UsersService) {}

  @Get(":id")
  async bitta(@Param("id") id: string) {     // async — Promise (2.11-JS)
    return await this.usersService.bitta(+id);   // NestJS Promise'ni o'zi kutadi
  }
  // NestJS async handler'ni avtomatik qo'llab-quvvatlaydi (5.10: catchAsync kerak emas!)
}

NestJS async — avtomatik: Express'da async xato uchun wrapper kerak edi (5.10: catchAsync). NestJS — async handler'ni avtomatik kutadi va xatoni exception filter'ga 8.7-bob uzatadi. Toza (wrapper yo'q).

Misol 12 — package.json scripts (CLI — 2.4)

json
{
  "scripts": {
    "start": "nest start",
    "start:dev": "nest start --watch",    // dev (o'zgarish kuzatuvi — 2.4)
    "start:debug": "nest start --debug --watch",
    "build": "nest build",                // production build
    "start:prod": "node dist/main",
    "test": "jest",                       // unit (8.11)
    "test:e2e": "jest --config ./test/jest-e2e.json"   // e2e (8.11)
  }
}

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

1) Biznes logikani controller'da

ts
//  controller'da mantiq (qalin — 2.7)
@Post() yarat(@Body() dto) { /* validatsiya, DB, email... */ }

//  service'ga uzatish (controller yupqa)
@Post() yarat(@Body() dto) { return this.service.yarat(dto); }

2) Provider'ni @Injectable'siz

ts
//  DI ishlamaydi (2.8)
export class UsersService {}

//  @Injectable
@Injectable() export class UsersService {}

3) Provider'ni module'ga qo'shmaslik

text
 service providers'da yo'q  "Cannot resolve dependencies" (2.6)
 @Module({ providers: [UsersService] })

4) new bilan instansiya (DI o'rniga)

ts
//  qo'lda yaratish (DI buziladi, test qiyin — 2.11)
const service = new UsersService();

//  DI (constructor)
constructor(private service: UsersService) {}

5) Express uslubida (NestJS naqshini buzish)

text
 NestJS'da Express middleware'ni hamma joyda qo'lda (struktura buziladi)
 NestJS naqshlari (guard/pipe/interceptor — 8.7)

6. Keng tarqalgan xatolar va yechimlari

Xato 1 — Nest can't resolve dependencies of the X

Sababi: provider module'ga qo'shilmagan, yoki @Injectable yo'q, yoki reflect-metadata (7.6: 2.10). Yechimi: providers'ga qo'sh; @Injectable; tsconfig (emitDecoratorMetadata).

Xato 2 — Cannot find module '@nestjs/...'

Sababi: paket o'rnatilmagan. Yechimi: npm i @nestjs/X.

Xato 3 — Controller route ishlamaydi (404)

Sababi: controller module'ga qo'shilmagan, yoki route prefiks 2.10-bob. Yechimi: controllers'ga qo'sh; prefiks tekshir.

Xato 4 — Dekorator ishlamaydi

Sababi: tsconfig'da experimentalDecorators yo'q (7.6: 2.3). Yechimi: yoq (nest new avtomatik sozlaydi).

Xato 5 — Service boshqa moduldan inject bo'lmaydi

Sababi: modul exports qilmagan 2.13-bob. Yechimi: exports: [Service] + import qiluvchi modulda imports: [OtherModule].

Xato 6 — Circular dependency

Sababi: ikki modul/service bir-birini import (aylana). Yechimi: forwardRef(() => X); arxitekturani qayta ko'rib chiq (9).


7. Integratsiya — bu mavzu stack'ning qayerida uchraydi

  • TypeScript (7): NestJS — TS-first; dekorator 7.6-bob, turlar.
  • Express 5.6-bob: NestJS ostida (adapter — 2.2); middleware.
  • DI 8.2-bob: keyingi bob — IoC chuqur.
  • DB (8.3, 6): TypeORM/Prisma/Mongoose modul.
  • DTO/Pipe 8.5-bob: validatsiya 5.9-bob.
  • Guards/Interceptors 8.7-bob: request lifecycle.
  • Auth (8.9, 5.15): JWT, Passport.
  • Clean architecture (9): SOLID, qatlamlar.
  • Testing 8.11-bob: DI mock.
  • Barcha 8-QISM: shu poydevorga quriladi.

8. Eng yaxshi amaliyotlar (best practices)

  • CLI bilan generatsiya (nest g resource — izchil — 2.4).
  • Controller yupqa, service qalin (HTTP vs biznes — 2.7, 2.8, 9).
  • Feature-based modullar (har resurs — modul — 2.5).
  • DI ishlat (new emas — constructor inject — 2.11).
  • Built-in exceptions (NotFoundException 404 — 8.7).
  • Global pipe/filter (main.ts — validatsiya — 2.10, 8.5).
  • exports/imports (shared modul — 2.13); @Global ehtiyot.
  • Default singleton (REQUEST scope ehtiyot — 2.14).
  • async handler (avtomatik — wrapper yo'q — Misol 11).
  • Request lifecycle'ni tushun (guard/pipe/interceptor joyi — 2.12).

9. Amaliy loyiha: "NestJS Birinchi Modul (CRUD)"

NestJS arxitekturasini mustahkamlash.

Maqsad

NestJS CLI bilan to'liq, qatlamli CRUD modul qurish: module, controller, service, DI, built-in exceptions.

Talablar (requirements)

  1. Loyiha: nest new bilan; bootstrap (global prefiks, validation pipe — Misol 1, 2.10).
  2. Feature module: nest g resource yoki qo'lda (users yoki o'z mavzu — Misol 3, 2.6).
  3. Controller: to'liq CRUD route (Get/Post/Patch/Delete, Param/Body/Query — Misol 4, 2.7).
  4. Service: biznes logika; controller yupqa (Misol 5, 2.8).
  5. DI: controller service; service boshqa service (Misol 7, 10, 2.11).
  6. Built-in exceptions: NotFound/Conflict (Misol 6, 8.7).
  7. Module tashkili: providers/controllers/exports (2.6, 2.13).
  8. async handler: Promise (Misol 11).
  9. Lifecycle hook: onModuleInit (Misol 8, 2.15).
  10. Global module (bonus): DatabaseModule (Misol 9, 2.13).

Maslahatlar (hint)

  • nest g resource users — to'liq CRUD 2.4-bob.
  • Controller yupqa (service'ga uzat — 2.7, 1-xato).
  • @Injectable + providers (2.8, 2-xato, 3-xato).
  • DI: constructor (new emas — 2.11, 4-xato).
  • NotFoundException 404 8.7-bob.
  • exports + imports (boshqa modul — 2.13, 5-xato).

"Tayyor" mezonlari (acceptance criteria)

  • Loyiha ishga tushadi (bootstrap, prefiks).
  • Feature module (controller+service+module).
  • To'liq CRUD route ishlaydi.
  • Controller yupqa, service qalin.
  • DI (service inject).
  • Built-in exceptions (404/409).
  • Module to'g'ri (providers/exports).
  • async handler.
  • Lifecycle hook.
  • (Bonus) Global module.

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


10. Xulosa va keyingi bobga ko'prik

Bu bobda NestJS poydevorini chuqur o'rgandik:

  • NestJS (2017, Kamil Myśliwiec, Angular ilhomi — 2.1, 2.3); Express ustida (adapter — 2.2); falsafa (consistency/scalability/testability/extensibility).
  • CLI (nest g resource — 2.4); tuzilma (feature-based — 2.5).
  • Uchlik: Module (guruhlash — 2.6), Controller (HTTP, yupqa — 2.7), Provider/Service (biznes, qalin — 2.8); birga 2.9-bob.
  • Bootstrap 2.10-bob; IoC konteyner/DI 2.11-bob; request lifecycle 2.12-bob; module turlari 2.13-bob; scope 2.14-bob; lifecycle hooks 2.15-bob.

Keyingi bob — 8.2-bob: Dependency Injection (chuqur). Arxitekturani bildik; endi NestJS'ning eng muhim, eng kuchli mexanizmini — Dependency Injection ni — chuqur o'rganamiz: IoC konteyner ichki ishlashi, provider turlari (useClass/useValue/useFactory), injection token, custom provider, scope. DI — NestJS'ning butun sehrining asosi (8.1'da ko'rdik; endi to'liq).


Foydalanilgan rasmiy/ishonchli manbalar

  • docs.nestjs.com — Introduction, Modules, Controllers, Providers, Lifecycle events
  • docs.nestjs.com/fundamentals — Custom providers, Injection scopes; NestFactory bootstrap
  • DigitalOcean / freeCodeCamp — NestJS DI guide; Medium — NestJS request lifecycle, Angular mental model

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
8.1-bob: NestJS kirish — arxitektura, modules, controllers, providers — Wisar