Asosiy bo'lim16 min read

Controllerlar

Controllerlar kiruvchi requestlarni qabul qilish va klientga response qaytarish uchun javob beradi.

Controllerlar kiruvchi requestlarni qabul qilish va klientga response qaytarish uchun javob beradi.

Controllerning vazifasi — ilova uchun aniq (specific) so‘rovlarni boshqarish. Routing mexanizmi har bir so‘rovni qaysi controller qayta ishlashini aniqlaydi. Ko‘pincha bitta controllerda bir nechta route bo‘ladi va har bir route turli action bajarishi mumkin.

Oddiy controller yaratish uchun biz class’lar va decoratorlardan foydalanamiz. Decoratorlar class’larni kerakli metadata bilan bog‘laydi va Nest’ga request’larni tegishli controllerlarga ulaydigan routing map yaratish imkonini beradi.

Hint

Ichki validation bilan CRUD controller’ni tez yaratish uchun CLI’dagi CRUD generatordan foydalanishingiz mumkin: nest g resource [name].

Routing

Quyidagi misolda biz asosiy controller’ni aniqlash uchun majburiy bo‘lgan @Controller() decoratoridan foydalanamiz. Biz ixtiyoriy route path prefix sifatida cats ni ko‘rsatamiz. @Controller() decoratorida path prefix ishlatish related route’larni bir joyga guruhlashga yordam beradi va takroriy kodni kamaytiradi. Masalan, agar cat entity’si bilan bog‘liq interaction’larni boshqaradigan route’larni /cats path’i ostida guruhlamoqchi bo‘lsak, @Controller() decoratorida cats prefix’ini belgilaymiz. Shunda fayldagi har bir route uchun path’ning shu qismini qayta-qayta yozishimizga to‘g‘ri kelmaydi.

TypeScript
cats.controller
1import { Controller, Get } from '@nestjs/common';
2
3@Controller('cats')
4export class CatsController {
5  @Get()
6  findAll(): string {
7    return 'This action returns all cats';
8  }
9}
Hint

CLI yordamida controller yaratish uchun shunchaki $ nest g controller [name] buyrug‘ini bajaring.

findAll() metodidan oldin qo‘yilgan @Get() HTTP request method decorator’i Nest’ga HTTP so‘rovlar uchun aniq endpoint’ga handler yaratishni bildiradi. Endpoint HTTP method (bu yerda GET) va route path bilan aniqlanadi. Xo‘sh, route path nima? Handler uchun route path controller’da e’lon qilingan (ixtiyoriy) prefix bilan metod decoratorida ko‘rsatilgan path’ni birlashtirish orqali hosil bo‘ladi. Biz har bir route uchun prefix (cats) belgilaganmiz va metod decoratorida aniq path bermaganimiz uchun Nest GET /cats so‘rovlarini shu handler’ga map qiladi.

Aytilganidek, route path ixtiyoriy controller path prefix’ini va metod decoratorida berilgan path string’ni o‘z ichiga oladi. Masalan, controller prefix cats bo‘lsa va metod decorator @Get('breed') bo‘lsa, natijaviy route GET /cats/breed bo‘ladi.

Yuqoridagi misolda, ushbu endpoint’ga GET so‘rov kelganda, Nest so‘rovni foydalanuvchi yozgan findAll() metodiga yo‘naltiradi. E’tibor bering: bu yerda metod nomi butunlay ixtiyoriy. Biz route’ni bog‘lash uchun metod e’lon qilishimiz kerak, lekin Nest metod nomiga maxsus ma’no yuklamaydi.

Bu metod 200 status code va mos response bilan qaytadi (bu misolda oddiy string). Nega bunday bo‘ladi? Buni tushuntirish uchun avval Nest response’larni boshqarishda ikki turli yondashuvdan foydalanishini bilishimiz kerak:

Standart (tavsiya etiladi) Ushbu built-in usulda, request handler JavaScript object yoki array qaytarsa, u avtomatik ravishda JSON’ga serialize qilinadi. Ammo JavaScript primitive type (masalan, string, number, boolean) qaytsa, Nest uni serialize qilishga urinmasdan, shunchaki qiymatning o‘zini yuboradi. Bu response handling’ni soddalashtiradi: qiymatni qaytaring, qolganini Nest o‘zi qiladi.

Bundan tashqari, response’ning status code’i default holatda doimo 200 bo‘ladi, faqat POST so‘rovlari uchun 201 ishlatiladi. Bu xatti-harakatni handler darajasida @HttpCode(...) decoratorini qo‘shib oson o‘zgartirishimiz mumkin (qarang: Status codes).
Kutubxonaga xos (Library-specific) Biz kutubxonaga xos (masalan, Express) response object’dan foydalanishimiz mumkin, u metod handler signature’iga @Res() decoratorini qo‘yish orqali inject qilinadi (masalan, findAll(@Res() response)). Bu yondashuvda siz native response handling metodlaridan foydalanish imkoniga ega bo‘lasiz. Masalan, Express’da response’ni response.status(200).send() kabi kod bilan qurishingiz mumkin.
Warning

Nest handler @Res() yoki @Next() ishlatayotganini aniqlasa, siz library-specific yondashuvni tanlaganingizni tushunadi. Agar ikkala yondashuv bir route ichida birgalikda ishlatilsa, Standart yondashuv shu route uchun avtomatik o‘chirib qo‘yiladi va kutilganidek ishlamaydi. Ikkalasidan bir vaqtda foydalanish uchun (masalan, cookie/header’larni qo‘yish uchun response object’ni inject qilib, qolganini framework’ga qoldirish) @Res({{ '{' }} passthrough: true {{ '}' }}) decoratorida passthrough opsiyasini true qiling.

Request object

Ko‘pincha handler’lar klientning request tafsilotlariga kirishni xohlaydi. Nest (default Express) underlying platform’ning request object’iga kirish imkonini beradi. Request object’ni olish uchun Nest’ga @Req() decoratori orqali uni handler signature’iga inject qilishni aytasiz.

TypeScript
cats.controller
1import { Controller, Get, Req } from '@nestjs/common';
2import type { Request } from 'express';
3
4@Controller('cats')
5export class CatsController {
6  @Get()
7  findAll(@Req() request: Request): string {
8    return 'This action returns all cats';
9  }
10}
Hint

express typings’dan foydalanish uchun (yuqoridagi request: Request parametri misolidagi kabi) @types/express paketini o‘rnatilganiga ishonch hosil qiling.

Request object HTTP so‘rovni ifodalaydi va query string, param’lar, HTTP header’lar hamda body uchun property’larni o‘z ichiga oladi (batafsil bu yerda). Ko‘p hollarda bu property’larga qo‘lda kirishingiz shart emas. Buning o‘rniga, @Body() yoki @Query() kabi dedicated decorator’lardan foydalanishingiz mumkin — ular out of the box mavjud. Quyida taqdim etilgan decorator’lar ro‘yxati va ular mos keladigan platformaga xos object’lar keltirilgan.

@Request(), @Req()req
@Response(), @Res()*res
@Next()next
@Session()req.session
@Param(key?: string)req.params / req.params[key]
@Body(key?: string)req.body / req.body[key]
@Query(key?: string)req.query / req.query[key]
@Headers(name?: string)req.headers / req.headers[name]
@Ip()req.ip
@HostParam()req.hosts

* Underlying HTTP platform’lar (masalan, Express va Fastify) bo‘yicha typings bilan moslik uchun Nest @Res() va @Response() decoratorlarini beradi. @Res()@Response() ning oddiy alias’i. Ikkalasi ham underlying native platform response object interface’ini to‘g‘ridan-to‘g‘ri expose qiladi. Ulardan foydalanganda, to‘liq imkoniyatlardan foydalanish uchun underlying kutubxona typings’ini (masalan, @types/express) ham import qilishingiz kerak. E’tibor bering: metod handler’da @Res() yoki @Response() ni inject qilganingizda, Nest shu handler uchun Library-specific mode’ga o‘tadi va response’ni boshqarish sizning mas’uliyatingizga aylanadi. Bunda response object’ida biror call orqali (masalan, res.json(...) yoki res.send(...)) response yuborishingiz shart, aks holda HTTP server “osilib qoladi” (hang).

Hint

O‘zingizning custom decorator’laringizni qanday yaratishni bilish uchun this bo‘limiga o‘ting.

Resurslar

Avval biz cats resursini olish uchun endpoint (GET route) aniqladik. Odatda biz yangi yozuvlar yaratadigan endpoint ham berishni xohlaymiz. Buning uchun POST handler yaratamiz:

TypeScript
cats.controller
1import { Controller, Get, Post } from '@nestjs/common';
2
3@Controller('cats')
4export class CatsController {
5  @Post()
6  create(): string {
7    return 'This action adds a new cat';
8  }
9
10  @Get()
11  findAll(): string {
12    return 'This action returns all cats';
13  }
14}

Shu qadar oson. Nest barcha standart HTTP metodlar uchun decorator’larni taqdim etadi: @Get(), @Post(), @Put(), @Delete(), @Patch(), @Options(), va @Head(). Bundan tashqari, @All() ularning barchasini handle qiladigan endpoint’ni aniqlaydi.

Route wildcard’lari

NestJS’da pattern-based route’lar ham qo‘llab-quvvatlanadi. Masalan, yulduzcha (*) path oxirida wildcard sifatida ishlatilishi va route oxiridagi istalgan belgilar kombinatsiyasini match qilishi mumkin. Quyidagi misolda, findAll() metodi abcd/ bilan boshlanadigan istalgan route uchun ishlaydi — undan keyin nechta belgi kelishi muhim emas.

TypeScript
1@Get('abcd/*')
2findAll() {
3  return 'This route uses a wildcard';
4}

'abcd/*' route path abcd/, abcd/123, abcd/abc va hokazolarni match qiladi. Tire ( -) va nuqta (.) string-based path’larda literal sifatida talqin qilinadi.

Bu yondashuv Express va Fastify’da ishlaydi. Biroq Express’ning eng so‘nggi versiyasi (v5) bilan routing tizimi yanada qat’iy bo‘lib qoldi. Oddiy Express’da route ishlashi uchun named wildcard ishlatishingiz kerak — masalan, abcd/*splat, bu yerda splat wildcard parameter’ining shunchaki nomi, maxsus ma’noga ega emas. Uni xohlagan nom bilan atashingiz mumkin. Shunga qaramay, Nest Express uchun compatibility layer bergani sababli, siz baribir yulduzcha (*)ni wildcard sifatida ishlata olasiz.

Route’ning o‘rtasida ishlatiladigan yulduzchalar haqida gapirganda, Express named wildcard’larni talab qiladi (masalan, ab{{ '{' }}*splat}cd), Fastify esa umuman bunday holatni qo‘llab-quvvatlamaydi.

Status code

Aytilganidek, response’lar uchun default status code doimo 200, faqat POST so‘rovlari uchun default 201 bo‘ladi. Bu xatti-harakatni handler darajasida @HttpCode(...) decoratorini qo‘llab oson o‘zgartirish mumkin.

TypeScript
1@Post()
2@HttpCode(204)
3create() {
4  return 'This action adds a new cat';
5}
Hint

HttpCode ni @nestjs/common paketidan import qiling.

Ko‘pincha status code statik bo‘lmaydi, balki turli omillarga bog‘liq bo‘ladi. Bunday holatda siz library-specific response ( @Res() orqali inject qilingan) object’dan foydalanishingiz (yoki xato bo‘lsa exception throw qilishingiz) mumkin.

Response header’lari

Custom response header berish uchun siz @Header() decoratoridan foydalanishingiz yoki library-specific response object’ni ishlatib, res.header() ni bevosita chaqirishingiz mumkin.

TypeScript
1@Post()
2@Header('Cache-Control', 'no-store')
3create() {
4  return 'This action adds a new cat';
5}
Hint

Header ni @nestjs/common paketidan import qiling.

Redirect

Response’ni ma’lum URL’ga yo‘naltirish uchun @Redirect() decoratoridan foydalanishingiz yoki library-specific response object orqali res.redirect() ni bevosita chaqirishingiz mumkin.

@Redirect() ikki argument qabul qiladi: url va statusCode, ikkalasi ham ixtiyoriy. statusCode default qiymati (agar berilmasa) 302 (Found).

TypeScript
1@Get()
2@Redirect('https://nestjs.com', 301)
Hint

Ba’zan HTTP status code yoki redirect URL’ni dinamik aniqlash kerak bo‘ladi. Buni HttpRedirectResponse interface’iga ( @nestjs/common dan) mos object qaytarish orqali bajaring.

Qaytarilgan qiymatlar @Redirect() decoratoriga berilgan argumentlarni override qiladi. Masalan:

TypeScript
1@Get('docs')
2@Redirect('https://docs.nestjs.com', 302)
3getDocs(@Query('version') version) {
4  if (version && version === '5') {
5    return { url: 'https://docs.nestjs.com/v5/' };
6  }
7}

Route parameter’lari

Request tarkibida dinamik data qabul qilish kerak bo‘lgan holatlarda statik path’li route’lar ishlamaydi (masalan, id’si 1 bo‘lgan cat’ni olish uchun GET /cats/1). Parametrli route’larni aniqlash uchun URL’dagi dinamik qiymatlarni ushlab qolish maqsadida route path’ga route parameter tokenlarini qo‘shishingiz mumkin. Quyidagi @Get() misolida route parameter tokenidan foydalanish ko‘rsatilgan. So‘ng bu route parameter’larini @Param() decoratoridan foydalanib olish mumkin — u metod signature’iga qo‘shiladi.

Hint

Parametrli route’lar statik path’lardan keyin e’lon qilinishi kerak. Bu parameterized path’lar statik path’ga mo‘ljallangan trafikni “olib qo‘yishi”ni oldini oladi.

TypeScript
1@Get(':id')
2findOne(@Param() params: any): string {
3  console.log(params.id);
4  return `This action returns a #${params.id} cat`;
5}

@Param() decoratori metod parametrini (yuqoridagi misolda params) decorate qiladi va route parameter’larini shu decorated metod parametri property’lari sifatida method ichida foydalanish imkonini beradi. Kodingizda ko‘ringanidek, id parameter’iga params.id orqali murojaat qilasiz. Muqobil tarzda, decoratorga aniq token berib, route parameter’iga nomi bo‘yicha bevosita murojaat qilishingiz mumkin.

Hint

Param ni @nestjs/common paketidan import qiling.

TypeScript
1@Get(':id')
2findOne(@Param('id') id: string): string {
3  return `This action returns a #${id} cat`;
4}

Sub-domain routing

@Controller decoratorida host opsiyasini berish mumkin — bu kiruvchi request’larning HTTP host’i ma’lum qiymatga mos kelishini talab qiladi.

TypeScript
1@Controller({ host: 'admin.example.com' })
2export class AdminController {
3  @Get()
4  index(): string {
5    return 'Admin page';
6  }
7}
Warning

Fastify nested router’larni qo‘llab-quvvatlamagani uchun, sub-domain routing ishlatayotgan bo‘lsangiz, default Express adapter’dan foydalanish tavsiya etiladi.

Route path kabi, host opsiyasi ham host nomining shu pozitsiyasidagi dinamik qiymatni ushlab qolish uchun tokenlardan foydalanishi mumkin. Quyidagi @Controller() misolida host parameter tokenidan foydalanish ko‘rsatilgan. Shu tarzda e’lon qilingan host parameter’lariga @HostParam() decoratorini metod signature’iga qo‘shib kirishingiz mumkin.

TypeScript
1@Controller({ host: ':account.example.com' })
2export class AccountController {
3  @Get()
4  getInfo(@HostParam('account') account: string) {
5    return account;
6  }
7}

State sharing

Boshqa dasturlash tillaridan kelgan dasturchilar uchun Nest’da deyarli hamma narsa kiruvchi request’lar o‘rtasida shared ekanini bilish hayratlanarli bo‘lishi mumkin. Bunga database connection pool kabi resurslar, global state’ga ega singleton service’lar va boshqalar kiradi. Muhim jihat shuki, Node.js request/response uchun Multi-Threaded Stateless Model’dan foydalanmaydi — ya’ni har bir request alohida thread’da ishlanmaydi. Natijada, Nest’da singleton instansiyalarni ishlatish ilovalarimiz uchun to‘liq xavfsiz.

Shunga qaramay, ba’zi edge case’larda controller’lar uchun request-based lifetime kerak bo‘lishi mumkin. Masalan, GraphQL ilovalarida per-request caching, request tracking yoki multi-tenancy’ni implement qilish. Injection scope’larni boshqarish haqida batafsil bu yerda o‘qing.

Asinxronlik

Biz zamonaviy JavaScript’ni, ayniqsa asynchronous data handling’ga urg‘u berishini yaxshi ko‘ramiz. Shu sababli Nest async funksiyalarni to‘liq qo‘llab-quvvatlaydi. Har bir async funksiya Promise qaytarishi kerak — bu esa Nest’ga “kechiktirilgan” qiymatni qaytarish imkonini beradi va Nest uni avtomatik resolve qiladi. Masalan:

TypeScript
cats.controller
1@Get()
2async findAll(): Promise<any[]> {
3  return [];
4}

Bu kod to‘liq valid. Biroq Nest bundan ham oldinga o‘tadi: route handler’lar RxJS observable streams qaytarishiga ham ruxsat beradi. Nest subscription’ni ichkarida o‘zi boshqaradi va stream tugagandan so‘ng yakuniy emitted qiymatni resolve qiladi.

TypeScript
cats.controller
1@Get()
2findAll(): Observable<any[]> {
3  return of([]);
4}

Ikkala yondashuv ham to‘g‘ri — ehtiyojingizga mosini tanlashingiz mumkin.

Request payload’lar

Oldingi misolda POST route handler klientdan hech qanday parameter qabul qilmagan edi. Keling, @Body() decoratorini qo‘shib buni to‘g‘rilaymiz.

Davom etishdan oldin (agar TypeScript ishlatayotgan bo‘lsangiz), DTO (Data Transfer Object) sxemasini aniqlashimiz kerak. DTO — data tarmoq orqali qanday yuborilishini belgilab beradigan object. DTO sxemasini TypeScript interface’lari yoki oddiy class’lar orqali aniqlashimiz mumkin. Biroq bu yerda classlardan foydalanishni tavsiya qilamiz. Nega? Class’lar JavaScript ES6 standartining bir qismi, shu sababli compile qilingan JavaScript’da real entity sifatida saqlanib qoladi. Aksincha, TypeScript interface’lar transpile jarayonida olib tashlanadi, ya’ni Nest runtime’da ularga murojaat qila olmaydi. Bu muhim, chunki Pipes kabi feature’lar runtime’da o‘zgaruvchilarning metatype’iga kirishni talab qiladi — bunga faqat class’lar orqali erishish mumkin.

CreateCatDto class’ini yarataylik:

TypeScript
create-cat.dto
1export class CreateCatDto {
2  name: string;
3  age: number;
4  breed: string;
5}

Unda 3 ta oddiy property bor. Endi yaratilgan DTO’ni CatsController ichida ishlatamiz:

TypeScript
cats.controller
1@Post()
2async create(@Body() createCatDto: CreateCatDto) {
3  return 'This action adds a new cat';
4}
Hint

Bizning ValidationPipe metod handler’iga kelishi kerak bo‘lmagan property’larni filtrlab tashlashi mumkin. Bu holatda biz acceptable property’larni whitelist qilib qo‘yamiz, whitelist’ga kirmagan property esa natijaviy object’dan avtomatik olib tashlanadi. CreateCatDto misolida whitelist — name, age, va breed property’lari. Batafsil bu yerda.

Query parameter’lar

Route’larda query parameter’larni qayta ishlashda ularni kiruvchi request’dan ajratib olish uchun @Query() decoratoridan foydalanishingiz mumkin. Keling, amalda qanday ishlashini ko‘ramiz.

Masalan, age va breed kabi query parameter’lar asosida cats ro‘yxatini filterlashni xohlaymiz. Avval CatsController ichida query parameter’larni aniqlaymiz:

TypeScript
cats.controller
1@Get()
2async findAll(@Query('age') age: number, @Query('breed') breed: string) {
3  return `This action returns all cats filtered by age: ${age} and breed: ${breed}`;
4}

Bu misolda, @Query() decoratori query string’dan age va breed qiymatlarini ajratib oladi. Masalan, quyidagi so‘rov:

Plaintext
1GET /cats?age=2&breed=Persian

natijada age = 2 va breed = Persian bo‘ladi.

Agar ilovangiz yanada murakkab query parameter’larni (masalan, nested object yoki array’lar) qayta ishlashi kerak bo‘lsa:

Plaintext
1?filter[where][name]=John&filter[where][age]=30
2?item[]=1&item[]=2

HTTP adapter’ingizni (Express yoki Fastify) mos query parser’dan foydalanishga sozlashingiz kerak bo‘ladi. Express’da siz extended parser’dan foydalanishingiz mumkin — u “boy” (rich) query object’larni qo‘llab-quvvatlaydi:

TypeScript
1const app = await NestFactory.create<NestExpressApplication>(AppModule);
2app.set('query parser', 'extended');

Fastify’da querystringParser opsiyasidan foydalanishingiz mumkin:

TypeScript
1const app = await NestFactory.create<NestFastifyApplication>(
2  AppModule,
3  new FastifyAdapter({
4    querystringParser: (str) => qs.parse(str),
5  }),
6);
Hint

qs — nesting va array’larni qo‘llab-quvvatlaydigan querystring parser. Uni npm install qs orqali o‘rnatishingiz mumkin.

Xatolarni boshqarish

Xatolarni boshqarish (ya’ni exception’lar bilan ishlash) bo‘yicha alohida bo‘lim bu yerda.

To‘liq resurs namunasi

Quyida bir nechta mavjud decorator’lardan foydalanib oddiy controller yaratish misoli keltirilgan. Bu controller ichki data’ga kirish va uni o‘zgartirish uchun bir nechta metodlarni taqdim etadi.

TypeScript
cats.controller
1import { Controller, Get, Query, Post, Body, Put, Param, Delete } from '@nestjs/common';
2import { CreateCatDto, UpdateCatDto, ListAllEntities } from './dto';
3
4@Controller('cats')
5export class CatsController {
6  @Post()
7  create(@Body() createCatDto: CreateCatDto) {
8    return 'This action adds a new cat';
9  }
10
11  @Get()
12  findAll(@Query() query: ListAllEntities) {
13    return `This action returns all cats (limit: ${query.limit} items)`;
14  }
15
16  @Get(':id')
17  findOne(@Param('id') id: string) {
18    return `This action returns a #${id} cat`;
19  }
20
21  @Put(':id')
22  update(@Param('id') id: string, @Body() updateCatDto: UpdateCatDto) {
23    return `This action updates a #${id} cat`;
24  }
25
26  @Delete(':id')
27  remove(@Param('id') id: string) {
28    return `This action removes a #${id} cat`;
29  }
30}
Hint

Nest CLI generator (schematic) taqdim etadi va u barcha boilerplate kodni avtomatik yaratadi — qo‘lda yozishdan qutqaradi va umumiy developer experience’ni yaxshilaydi. Bu feature haqida batafsil bu yerda.

Ishga tushirish

CatsController to‘liq aniqlangan bo‘lsa ham, Nest hozircha u haqida bilmaydi va class instansiyasini avtomatik yaratmaydi.

Controllerlar har doim modul tarkibida bo‘lishi shart, shu sababli biz @Module() decoratorida controllers array’ini ko‘rsatamiz. Root AppModuledan boshqa modullarni aniqlamaganimiz uchun, CatsControllerni ro‘yxatdan o‘tkazish uchun shu moduldan foydalanamiz:

TypeScript
app.module
1import { Module } from '@nestjs/common';
2import { CatsController } from './cats/cats.controller';
3
4@Module({
5  controllers: [CatsController],
6})
7export class AppModule {}

Biz @Module() decoratori orqali modul class’iga metadata biriktirdik, endi Nest qaysi controllerlar mount qilinishi kerakligini oson aniqlay oladi.

Library-specific yondashuv

Hozirgacha biz response’larni boshqarishning standart Nest usulini ko‘rib chiqdik. Yana bir yondashuv — kutubxonaga xos response object’dan foydalanish. Aniq response object’ni inject qilish uchun @Res() decoratoridan foydalanamiz. Farqlarni ko‘rsatish uchun CatsControllerni quyidagicha qayta yozamiz:

TypeScript
1import { Controller, Get, Post, Res, HttpStatus } from '@nestjs/common';
2import { Response } from 'express';
3
4@Controller('cats')
5export class CatsController {
6  @Post()
7  create(@Res() res: Response) {
8    res.status(HttpStatus.CREATED).send();
9  }
10
11  @Get()
12  findAll(@Res() res: Response) {
13     res.status(HttpStatus.OK).json([]);
14  }
15}

Bu yondashuv ishlaydi va response object ustidan to‘liq nazorat (masalan, header’larni boshqarish va kutubxonaga xos feature’lardan foydalanish) berib, ko‘proq moslashuvchanlik taqdim etadi. Biroq undan ehtiyotkorlik bilan foydalanish kerak. Odatda bu usul ancha noaniqroq va ayrim kamchiliklarga ega. Asosiy kamchiligi — kod platformaga bog‘lanib qoladi: turli underlying kutubxonalar response object uchun turlicha API’ga ega bo‘lishi mumkin. Bundan tashqari, test qilish ham qiyinlashadi, chunki response object’ni mock qilish va boshqa ishlar kerak bo‘ladi.

Bundan tashqari, bu yondashuvni ishlatganda Nest’ning standart response handling’iga tayanadigan ayrim feature’lar bilan moslikni yo‘qotasiz, masalan Interceptorlar va @HttpCode() / @Header() decoratorlari. Buni hal qilish uchun passthrough opsiyasini quyidagicha yoqishingiz mumkin:

TypeScript
1@Get()
2findAll(@Res({ passthrough: true }) res: Response) {
3  res.status(HttpStatus.OK);
4  return [];
5}

Bu yondashuv bilan siz native response object bilan ishlashingiz mumkin (masalan, muayyan shartlarga ko‘ra cookie yoki header qo‘yish), shu bilan birga qolganini framework’ga boshqartirishda davom etasiz.