IlmHamroh
JavaScript Full-stack/30-qism. NestJS51/65-dars17 daqiqa
Mundarija (28)

Fastify adapter bilan NestJS: FastifyAdapter, farqlar va o'lchov

Qisqacha: Nest HTTP'ni o'zi qilmaydi — u adapter orqali Express yoki Fastify ustida ishlaydi. Fastify'ga o'tish uchun @nestjs/platform-fastify o'rnatiladi va NestFactory.create(AppModule, new FastifyAdapter()) yoziladi. Controller'lar o'zgarmaydi, lekin platformaga tegadigan hamma narsa o'zgaradi: @Res()/@Req() obyektlari, middleware ichidagi req, Express plaginlari (helmet, multer, static). Kanon o'lchovida Fastify Express'dan ~1.5× tez chiqdi. Nest qatlamining narxi esa 4–18 % bo'ldi. vazifalar-api baribir Express'da qoldi — kodi Express'ga ko'p joyda bog'langan, bazali endpoint'larda esa tezlik farqini baza yeb qo'yadi.

Bu darsda

  • Nest'ning adapter tuzilmasini va Fastify'ga o'tish uchun nima o'zgarishini tushuntirasiz.
  • Express va Fastify adapterlari bir xil kodga qanday har xil javob berishini haqiqiy chiqishda ko'rasiz.
  • @Res(), @Req() va middleware'dagi farqlar nega muhimligini bilasiz.
  • Besh xil serverning o'lchovini o'qiysiz va Nest qatlamining narxini hisoblaysiz.
  • Kanon nega Express adapterida qolganini asoslab bera olasiz.

Oldin bilishingiz kerak: Fastify, NestJS nima va nega, Controller'lar va route dekoratorlari, Middleware Nest'da, NestJS e2e testlari.

O'tgan darsda vazifalar-api ning test to'plamini Nest'da yurgizdik va commit qildik. Endi xavfsiz o'zgartirish qila olamiz — har qadamni testlar tekshiradi. Shu imkoniyatdan foydalanib, bir katta savolni o'lchaymiz: Express o'rniga Fastify qo'yilsa nima bo'ladi?

1. Nega bu kerak?

29-qismda Fastify'ni alohida o'rgandik (Fastify). U Express'dan tezroq: JSON sxemadan serializatsiya, yengil marshrutlash, plagin tizimi. 29-qism kanon o'lchovida oddiy GET'da Fastify Express'dan qariyb ikki baravar ko'p so'rov qabul qilgandi.

Nest'ning birinchi darsida aytilgandi: Nest — freymvork ustidagi freymvork (NestJS nima va nega). Pastda Express yoki Fastify ishlaydi, Nest esa tepada modul, DI va dekoratorlarni beradi. Demak, savol tabiiy: Nest loyihasida pastki qavatni almashtirsa bo'ladimi va bunga arziydimi?

O'xshatish: avtobus kompaniyasi bir xil marshrut va haydovchilar bilan ishlaydi, faqat avtobus markasini almashtirmoqchi. Yo'lovchilar (controller'lar) farqni sezmaydi. Lekin ta'mirchilar (middleware, plaginlar) eski markaning ehtiyot qismlarini olib yurgan bo'lsa — ular hammasini qaytadan o'rganishi kerak.

2. Adapter: Nest va platforma orasidagi qatlam

2.1 Qanday ishlaydi

Nest yadrosi (@nestjs/core) HTTP haqida deyarli hech narsa bilmaydi. U so'rovni "adapter" deb ataladigan klassga topshiradi. @nestjs/platform-express dagi ExpressAdapter — sukut. @nestjs/platform-fastify dagi FastifyAdapter — muqobil. Ikkalasi bir xil interfeysni bajaradi: marshrut ro'yxatga olish, javob yuborish, status qo'yish, sarlavha o'rnatish.

flowchart TB
  C["Controller: return qiymat"] --> N["Nest yadrosi: guard, pipe, interceptor"]
  N --> A{"Adapter"}
  A --> E["ExpressAdapter → res.json()"]
  A --> F["FastifyAdapter → reply.send()"]
  R["@Res() / @Req() / middleware"] -. "adapterni chetlab, to'g'ridan" .-> E
  R -. "to'g'ridan" .-> F

Diagrammaning yuqori yo'li — platformadan mustaqil: controller qiymat qaytaradi, adapter uni yuboradi. Pastdagi punktir — xavfli yo'l: @Res(), @Req() va middleware adapterni chetlab, platformaning o'z obyektlariga tegadi. Platforma almashsa, aynan shu joylar buziladi.

2.2 JS modelida

Bu g'oyani kichik modelda ko'ramiz (brauzerda ishlaydi):

js
// Nest yadrosi handler natijasini oladi, javobni ADAPTER yuboradi
const expressAdapter = {
  nomi: "Express",
  yubor(res, status, qiymat) {
    res.status(status).json(qiymat);
  },
};
const fastifyAdapter = {
  nomi: "Fastify",
  yubor(reply, status, qiymat) {
    reply.code(status).send(qiymat);
  },
};

// soxta javob obyektlari: har platformaning o'z metodlari
const expressRes = () => ({
  status(s) { this.s = s; return this; },
  json(q) { console.log(`  Express res.json: ${this.s}`, q); },
});
const fastifyReply = () => ({
  code(s) { this.s = s; return this; },
  send(q) { console.log(`  Fastify reply.send: ${this.s}`, q); },
});

// controller platformani bilmaydi — faqat qiymat qaytaradi
const vazifaOl = () => ({ id: 1, matn: "Non olish" });

for (const [adapter, res] of [
  [expressAdapter, expressRes()],
  [fastifyAdapter, fastifyReply()],
]) {
  console.log(adapter.nomi + ":");
  adapter.yubor(res, 200, vazifaOl());
}

// @Res() bilan controller platformaga bog'lanadi
const xomController = (res) => res.json({ id: 1 });
try {
  xomController(fastifyReply());
} catch (e) {
  console.log("Fastify'da @Res():", e.message);
}

Konsolda:

text
Express:
  Express res.json: 200 { id: 1, matn: 'Non olish' }
Fastify:
  Fastify reply.send: 200 { id: 1, matn: 'Non olish' }
Fastify'da @Res(): res.json is not a function

vazifaOl ikki platformada ham ishladi — u faqat obyekt qaytaradi. xomController esa Express metodini (res.json) to'g'ridan chaqirdi va Fastify'da yiqildi. Model soddalashtirilgan: haqiqiy adapterlar sarlavha, oqim (stream) va xatolarni ham boshqaradi. Lekin chegara aynan shu yerda.

3. Fastify'ga o'tish: o'rnatish va main.ts

3.1 Paket va bootstrap

bash
npm i @nestjs/platform-fastify@12.2.0

Paket o'zi bilan fastify ni olib keladi — biz o'rnatganda 5.12.7 keldi (29-qismdagi bilan bir xil). @nestjs/platform-express endi kerak emas, lekin olib tashlashdan oldin kodda Express'ga tegadigan joy qolmaganiga ishonch hosil qiling.

main.ts:

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

const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter(),
);
await app.listen(Number(process.env.PORT ?? 3000), "0.0.0.0");

Ikki yangi narsa:

  • NestFastifyApplication — tip. U app da Fastify'ga xos metodlarni ochadi (app.register(...) — Fastify plaginini ulash). Express'da shunga o'xshash NestExpressApplication bor edi (Bootstrap).
  • listen(port, "0.0.0.0") — Nest hujjatiga ko'ra Fastify sukut bo'yicha faqat localhost da tinglaydi. Konteyner ichida (33-qism) tashqaridan ulanish uchun "0.0.0.0" kerak. Express sukut bo'yicha hamma interfeysda tinglaydi — bu farqni unutish konteynerda "ilova ishlayapti, lekin ulanib bo'lmaydi" xatosini beradi.

new FastifyAdapter({ logger: true, bodyLimit: 16_384 }) — Fastify'ning o'z sozlamalari adapterga beriladi.

3.2 Controller o'zgarmaydi

Shu darsning tajribasi uchun demo controller yozdik. @Controller, @Get, @Post, @Body — oddiy Nest kodi, platforma haqida hech narsa yo'q:

ts
@Controller("v")
class VController {
  @Get()
  ol() {
    return { matn: "Non olish #uy" };
  }

  @Post()
  yoz(@Body() tana: unknown) {
    return { olindi: tana ?? null };
  }
}

Nest'ning asosiy va'dasi shu: qiymat qaytaradigan controller ikki adapterda ham ishlaydi. Lekin keyingi bo'lim ko'rsatadiki, "ishlaydi" va "bir xil ishlaydi" — har xil gap.

Tekshirib ko'ring: Ilova Docker konteynerida, app.listen(3000) bilan ishga tushdi. Express adapterida tashqaridan ulanish bor edi, Fastify'ga o'tgach — yo'q. Nima tuzatiladi?

Javob

Fastify sukut bo'yicha faqat localhost (konteynerning o'z ichi) da tinglaydi. Tashqi ulanish konteyner tarmoq interfeysi orqali keladi — u yerda hech kim tinglamaydi. Tuzatish: app.listen(3000, "0.0.0.0").

4. Bir xil kod — ikki xil javob

4.1 Tajriba

Demo controller'ga ikki marshrut va bitta middleware qo'shdik. @Res() marshruti javob obyektida json metodi bormi deb so'raydi, @Req() esa so'rov obyektining klass nomini qaytaradi. Middleware har so'rovda req turini, url va path ni yozib qo'yadi:

ts
@Injectable()
class IzMiddleware implements NestMiddleware {
  use(
    req: { url?: string; path?: string; constructor: Function },
    _res: unknown,
    next: () => void,
  ): void {
    const tur = req.constructor.name;
    izlar.push(`${tur} url=${req.url} path=${req.path}`);
    next();
  }
}

// VController ichida:
  @Get("res")
  xom(@Res() res: { json?: unknown; status: (n: number) => {
    send: (x: unknown) => void } }) {
    res.status(200).send({ jsonBormi: typeof res.json });
  }

  @Get("req")
  sorov(@Req() req: { constructor: { name: string }; raw: unknown }) {
    return { req: req.constructor.name, raw: typeof req.raw };
  }

Middleware modulda consumer.apply(IzMiddleware).forRoutes("v") bilan ulangan (Middleware Nest'da). Bir xil fayl ikki marta yurgizildi: bir marta new FastifyAdapter() bilan, bir marta adaptersiz (sukut — Express). Har safar oltita so'rov (biz ishga tushirdik: NestJS 12.2.0, fastify 5.12.7, Node 24.21.0). Ikki chiqishni qatorma-qator solishtiring: qaysi qatorlar bir xil, qaysilari farq qiladi?

Express adapteri:

text
GET /v: 200 {"matn":"Non olish #uy"}
POST json: 201 {"olindi":{"matn":"Sut"}}
POST text/plain: 201 {"olindi":null}
POST bo'sh json: 201 {"olindi":{}}
@Res(): 200 {"jsonBormi":"function"}
@Req(): 200 {"req":"IncomingMessage","raw":"undefined"}
middleware: IncomingMessage url=/ path=/

Fastify adapteri:

text
GET /v: 200 {"matn":"Non olish #uy"}
POST json: 201 {"olindi":{"matn":"Sut"}}
POST text/plain: 201 {"olindi":"Sut"}
POST bo'sh json: 400 {"statusCode":400,"message":"Body cannot be empty when content-type is set to 'application/json'"}
@Res(): 200 {"jsonBormi":"undefined"}
@Req(): 200 {"req":"Request","raw":"object"}
middleware: IncomingMessage url=/ path=undefined

4.2 Farqlarni o'qiymiz

So'rov Express Fastify
oddiy GET, JSON POST bir xil bir xil
text/plain tana e'tiborsiz (null) satr sifatida qabul
bo'sh tana + JSON turi {} 400 xato
@Res() obyekti res.json bor res.json yo'q
@Req() obyekti Node IncomingMessage FastifyRequest, xomi — req.raw
middleware'dagi req.path / undefined

Har qatorni qisqacha:

  • text/plain. Nest Express'da faqat JSON va forma parserini ulaydi — boshqa turdagi tana o'qilmaydi. Fastify'da text/plain parseri ichida bor. Natija: bir xil so'rovga controller bir adapterda null, ikkinchisida satr oladi. Validatsiya bo'lmasa — jim farq.
  • Bo'sh JSON. Fastify xabari: "Body cannot be empty when content-type is set to 'application/json'" — "content-type application/json qo'yilgan bo'lsa, tana bo'sh bo'lishi mumkin emas". Xato javobi ham Problem Details emas, Nest'ning sukut shakli. vazifalar-api bunday holatda o'z formatini beradi — Fastify'da u yana qayta yozilishi kerak.
  • @Res(). Fastify'ning javob obyekti — FastifyReply: res.status().send() bor, res.json() yo'q. Controller'lar darsida @Res() ni "oxirgi chora" degandik — mana yana bir sababi.
  • @Req(). Fastify o'z so'rov obyektini beradi, Node'ning xom so'rovi req.raw ichida. Express'da esa so'rov Node obyektining o'zi (ustiga metodlar qo'shilgan).
  • Middleware. Ikkala adapterda ham middleware Node'ning xom IncomingMessage ini oladi. Fastify'da Express qo'shadigan req.path yo'q. url esa ikkalasida ham / — forRoutes("v") ulangan yo'l prefiksi kesilgan. Kanon Express'da xuddi shu kesilishni topgan: yo'l bilan ulangan middleware ichida req.path to'liq yo'l emas (Middleware Nest'da). Middleware'da yo'lni req.originalUrl (Express) yoki req.raw.url (Fastify) dan olish kerak.

Diqqat: Adapter almashtirilgandan keyin "testlar o'tdi" yetmaydi — qaysi testlar borligiga qarang. Yuqoridagi text/plain farqini faqat shunday tanali so'rov yuboradigan test ushlaydi. vazifalar-api da 415 testlari bor (Guard'lar) — ular shu farqni darhol ko'rsatadi.

5. Express plaginlari o'rniga Fastify plaginlari

Express ekotizimidagi middleware'lar Fastify'da to'g'ridan ishlamaydi. Ularning Fastify muqobillari bor:

Express Fastify Nest'da ulash
helmet @fastify/helmet await app.register(helmet)
multer (FileInterceptor) @fastify/multipart app.register(...) + o'z interceptor
express.static @fastify/static app.useStaticAssets(...) (adapter qo'llaydi)
cors ichki app.enableCors(...)
cookie-parser @fastify/cookie app.register(...)

app.register — Fastify'ning plagin ulash usuli (29-qism, Fastify). Nest uni NestFastifyApplication orqali ochadi. Muhim tafsilot: Nest'ning @nestjs/platform-express dagi FileInterceptor (keyinroq Fayl yuklash NestJS'da darsida) Multer'ga bog'langan — Fastify'da ishlamaydi. Fayl yuklash Fastify'da @fastify/multipart va o'zingiz yozgan ishlovchi bilan qilinadi.

Halol aytamiz: @fastify/helmet va @fastify/multipart ni kanon ham, biz ham sinamadik. Jadval Nest hujjati (Performance (Fastify) bo'limi) va paket hujjatlariga asoslangan (2026-11).

6. O'lchov: besh server

6.1 Tajriba sharti

Kanon bir xil endpoint'ni besh xil serverda yozdi: xom node:http, Express 5, Fastify 5, Nest+Express va Nest+Fastify. Ikki so'rov: GET /v (kichik JSON qaytaradi) va POST /v (JSON tanani o'qib, qaytaradi). autocannon alohida jarayonda, 10 ulanish, har server navbat bilan, 5 aylana × 3 s. Bitta mashina, bir vaqtda, mashina boshqa ishlar bilan band — mutlaq req/s emas, nisbat muhim. Nest varianti juda sodda:

ts
@Controller("v")
class C {
  @Get() ol() { return JAVOB; }
  @Post() yoz(@Body() b: object) { return { ...b, id: 2 }; }
}
@Module({ controllers: [C] }) class M {}

const nestEx = await NestFactory.create(M, { logger: false });
const nestFa = await NestFactory.create<NestFastifyApplication>(
  M, new FastifyAdapter(), { logger: false },
);

Bitta modul, ikkita ilova — farq faqat adapterda.

6.2 Natija

GET /v, mediana. Asos — Nest+Express = 100 %:

GET /v: soniyasiga so'rov (Nest+Express = 100 %)
  • Nest+Express2 883 req/s100 %
  • Express 53 391 req/s118 %
  • Nest+Fastify5 013 req/s174 %
  • Fastify 55 225 req/s181 %
  • node:http5 722 req/s198 %

Manba: Kanon o'lchovi (IlmHamroh, 2026-10-28): autocannon, 10 ulanish, 5 × 3 s, bitta mashina, bir vaqtda, mashina band

POST /v (JSON tana), mediana req/s: node:http 4 282, Express 2 358, Fastify 3 764, Nest+Express 1 995, Nest+Fastify 3 103.

Raqamlardan uchta xulosa:

  1. Fastify Express'dan ~1.5× tez: GET'da 5 225 / 3 391 ≈ 1.54, POST'da 3 764 / 2 358 ≈ 1.60.
  2. Nest qatlamining narxi. Express ustida: GET 2 883 / 3 391 ≈ 0.85, ya'ni −15 %; POST ~−15 %. Fastify ustida: GET 5 013 / 5 225 ≈ 0.96 (−4 %), POST 3 103 / 3 764 ≈ 0.82 (~−18 %). Nest'ning o'z ishi (guard, pipe, interceptor zanjirini aylanib chiqish) ikkalasida ham bor.
  3. Nest+Fastify toza Express'dan tez: 5 013 va 3 391. Nest'ning "sekinligi" haqida gap bo'lsa — adapter tanlovi Nest qatlamidan ko'proq ta'sir qiladi.

Raqamlarning oralig'i keng edi (masalan, Fastify GET 4 470–20 947). Bu — mashina bandligi belgisi. Shuning uchun biz faqat medianalar nisbatiga tayanamiz.

6.3 Ishga tushish vaqti — tuzoqli raqam

Tajriba chiqishining birinchi qatori:

text
Nest ilova yaratish+listen (shu jarayonda, issiq import): Express adapter 4992 ms, Fastify adapter 22 ms

Bu raqamdan "Fastify 200 marta tez ishga tushadi" degan xulosa chiqarmang. Kodga qarang: Express ilovasi birinchi yaratilgan. U Nest yadrosini yuklash, metama'lumotni yig'ish va JIT isinishi narxini to'ladi. Fastify ilovasi ikkinchi bo'lib, tayyor narsalardan foydalandi. Adolatli o'lchov uchun har adapter alohida jarayonda, bir necha marta ishga tushirilishi kerak edi — kanon buni qilmagan. Bu raqam o'lchov tartibi natijaga qanday ta'sir qilishini ko'rsatadigan yaxshi misol. O'lchov usullarini keyinroq Yuklama va stress testlari darsida chuqur o'rganamiz.

Tekshirib ko'ring: Nest+Express 2 883, Express 3 391 req/s. Bir so'rovga Nest qancha vaqt qo'shadi (taxminan, ms)?

Javob

10 ulanish bilan bir so'rov o'rtacha vaqti ≈ ulanishlar / RPS. Express: 10 / 3 391 ≈ 2.95 ms; Nest+Express: 10 / 2 883 ≈ 3.47 ms. Farq ≈ 0.5 ms. Bazaga bitta so'rov odatda 1–20 ms oladi — shuning uchun haqiqiy endpoint'da bu farq sezilmay qoladi (keyingi bo'lim).

7. Nega vazifalar-api Express'da qoldi

7.1 Express'ga bog'langan joylar

Kanon kodni ko'rib chiqdi. Adapter almashsa qayta yoziladigan joylar:

  • res.links, res.location, res.attachment — Express javob metodlari (sahifalash Link sarlavhasi, Location, eksport fayli nomi).
  • express.static — statik fayllar, Range va ETag bilan.
  • express.json + tanaXatosi — 16 KB chegarasi, merge-patch+json turi va tana xatosining Problem Details shakli.
  • req.is(...) — 415 guard'i Content-Type ni Express metodi bilan tekshiradi.
  • helmet va cors — Express middleware'lari sifatida ulangan.
  • Idempotentlik middleware'i — res.json ni o'rab, javobni saqlaydi (Middleware Nest'da).
  • @Res({ passthrough: true }) qatnashgan marshrutlar.

Bu ro'yxat 25–29-qismlardagi hamma ishning natijasi: kod Express'da yozilgan va sinalgan.

7.2 Tezlik farqi bazada yo'qoladi

Hello world o'lchovida Nest+Express va Nest+Fastify farqi katta. Lekin vazifalar-api ning haqiqiy endpoint'lari bazaga boradi. Kanon Express (27-qism) va Nest (30-qism) versiyalarini bitta mashinada, Postgres bilan o'lchadi:

Endpoint (postgres) Express Nest+Express
GET /v1/vazifalar/1 825 555
GET /v1/teglar 845 606
PATCH /v1/vazifalar/1 71 69

PATCH da farq yo'q: so'rov qatorni qulflaydi va baza tezligi hal qiladi — HTTP qatlami qanchalik tez bo'lmasin. Bu jadvalni NestJS prodakshnda darsida to'liq o'qiymiz.

Fastify'ni vazifalar-api ning o'zida kanon o'lchamagan — buning uchun avval yuqoridagi ro'yxatni qayta yozish kerak edi. Halol xulosa: GET'larda Fastify foyda berishi mumkin, yozadigan endpoint'larda (PATCH, POST) — deyarli yo'q. Narxi esa sinalgan kodni qayta yozish va qayta sinash.

Mezon Express adapteri Fastify adapteri
Xom tezlik (hello world) asos ~1.5–1.7×
Bazali endpoint asos farq kichrayadi
Ekotizim (Nest hujjati, misollar) eng keng yaxshi, lekin kamroq
vazifalar-api kodi o'zgarishsiz ~7 joy qayta yoziladi

Kanon qarori: Express adapteri qoladi. Yangi Nest loyihasini noldan boshlasangiz va ko'p yengil GET kutilsa — Fastify jiddiy variant. Boshidan @Res() va Express middleware'larisiz yozish shart.

8. Ko'p uchraydigan xatolar

Belgi Sabab Davosi
res.json is not a function @Res() Express metodi bilan, adapter Fastify res.status().send() yoki @Res() siz
Konteynerda ulanib bo'lmaydi Fastify sukut — localhost listen(port, "0.0.0.0")
Express middleware ishlamaydi yoki xato beradi req.path, res.locals kabi Express qo'shimchalari yo'q @fastify/* plagini yoki Nest guard/interceptor
400 "Body cannot be empty…" bo'sh tana + JSON turi (Express'da o'tardi) mijozni tuzating yoki tana parserini sozlang
FileInterceptor ishlamaydi Multer Express'ga bog'langan @fastify/multipart

9. Mashqlar

Mashqlar kurs/mashqlar/30/51-fastify/ da.

1-mashq (oson): nima o'zgaradi?

Express'dan Fastify adapteriga o'tdingiz. To'ldiring:

  • return { id: 1 } qaytaradigan controller o'zgaradimi? —
  • @Res() res bilan res.json(x) ishlaydimi? —
  • Fastify'da xom Node so'rovi qaysi xususiyatda? req.
  • Konteyner uchun listen ning ikkinchi argumenti:
Yechim
  • yo'q — qiymat qaytarish platformadan mustaqil, javobni adapter yuboradi.
  • yo'q — FastifyReply da json metodi yo'q, send bor.
  • raw — FastifyRequest.raw — Node IncomingMessage.
  • 0.0.0.0 — Fastify sukut bo'yicha faqat localhost da tinglaydi.

2-mashq (o'rta): Nest qatlami narxini hisoblang

Kanon medianalari (req/s) obyektda berilgan. Har platforma (Express, Fastify) va har so'rov (GET, POST) uchun Nest qatlami narxini foizda hisoblang: (nest / toza − 1) × 100, butun songa yaxlitlang. Natija: "GET Express: -15 %" shaklidagi to'rt qator. Ishora: Math.round va shablon satr (Math).

Yechim
js
const o = {
  GET: { Express: 3391, "Nest+Express": 2883,
    Fastify: 5225, "Nest+Fastify": 5013 },
  POST: { Express: 2358, "Nest+Express": 1995,
    Fastify: 3764, "Nest+Fastify": 3103 },
};

for (const [sorov, q] of Object.entries(o)) {
  for (const p of ["Express", "Fastify"]) {
    const narx = Math.round((q[`Nest+${p}`] / q[p] - 1) * 100);
    console.log(`${sorov} ${p}: ${narx} %`);
  }
}

Konsolda:

text
GET Express: -15 %
GET Fastify: -4 %
POST Express: -15 %
POST Fastify: -18 %

Nest qatlami har doim narx oladi: 4–18 %. POST'da Fastify ustidagi narx kattaroq chiqdi — Fastify o'zi tez bo'lgani uchun Nest qo'shgan ish nisbatan ko'proq ko'rinadi. Mashina band bo'lgani uchun bu foizlar taxminiy.

3-mashq (qiyin): ikki platformali javob yordamchisi

Paketsiz model. javobYubor(res, status, qiymat) funksiyasini yozing: res.json funksiya bo'lsa — Express uslubida (res.status(s).json(q)), aks holda res.code bo'lsa — Fastify uslubida (res.code(s).send(q)), ikkalasi ham yo'q bo'lsa — "noma'lum platforma" xatosi. Darsdagi soxta expressRes/fastifyReply ga o'xshash ikki obyekt va bitta bo'sh obyekt bilan sinang. Ishora: typeof x === "function" (typeof).

Yechim
js
function javobYubor(res, status, qiymat) {
  if (typeof res.json === "function") {
    return res.status(status).json(qiymat);
  }
  if (typeof res.code === "function") {
    return res.code(status).send(qiymat);
  }
  throw new Error("noma'lum platforma");
}

const expressRes = {
  status(s) { this.s = s; return this; },
  json(q) { console.log("express", this.s, JSON.stringify(q)); },
};
const fastifyReply = {
  code(s) { this.s = s; return this; },
  send(q) { console.log("fastify", this.s, JSON.stringify(q)); },
};

for (const res of [expressRes, fastifyReply, {}]) {
  try {
    javobYubor(res, 201, { id: 7 });
  } catch (e) {
    console.log("xato:", e.message);
  }
}

Konsolda:

text
express 201 {"id":7}
fastify 201 {"id":7}
xato: noma'lum platforma

Bu — kichik "adapter". Nest buni o'zi qiladi, agar controller qiymat qaytarsa. @Res() ishlatsangiz, shunday yordamchini o'zingiz yozishga majbur bo'lasiz. Undan ham yaxshisi — @Res() ni ishlatmaslik.

10. Loyiha qadami: bu darsda kod o'zgarmaydi

vazifalar-api Express adapterida qoladi. Sabablari «Nega vazifalar-api Express'da qoldi» bo'limida: kodning yetti joyi Express'ga bog'langan, bazali endpoint'larda tezlik farqi kichik.

Fastify'ni o'z ko'zingiz bilan ko'rmoqchi bo'lsangiz, alohida tajriba papkasida qiling — loyihaga tegmasdan:

bash
mkdir fastify-tajriba && cd fastify-tajriba
npm init -y
npm i @nestjs/core@12.2.0 @nestjs/common@12.2.0 \
  @nestjs/platform-fastify@12.2.0 @nestjs/platform-express@12.2.0 \
  reflect-metadata rxjs

«Bir xil kod — ikki xil javob» bo'limidagi controller'ni ikki adapterda yurgizing va oltita so'rovning natijasini solishtiring. Commit yo'q.

11. Real ishda

  • Fastify adapteri yuqori yuklamali API'larda tanlanadi: ko'p yengil GET, kesh, proxy xizmatlari. Ko'p jamoa esa Express'da qoladi — ekotizim va o'rganilgan kod uchun.
  • Platformadan mustaqil kod — yaxshi Nest odati: @Res() va @Req() dan qochish, sarlavhani @Header() yoki interceptor bilan qo'yish, middleware o'rniga guard/interceptor. Shunday kod keyinroq adapterni almashtirishga tayyor.
  • O'lchov madaniyati: "Fastify tezroq" degan gapga ishonib ko'chmaslik — o'z endpoint'ingizni, o'z bazangiz bilan o'lchash. Bu darsdagi ishga tushish vaqti raqami — o'lchov tartibi xatosining tipik misoli.
  • Intervyu: "Nest'da Express va Fastify adapteri farqi?", "Fastify'ga o'tishda nima buziladi?", "Nega @Res() ishlatmaslik tavsiya etiladi?".

Xulosa

  • Nest HTTP'ni adapter orqali qiladi: ExpressAdapter (sukut) yoki FastifyAdapter; controller qiymat qaytarsa — platformadan mustaqil.
  • @Res(), @Req(), middleware va Express plaginlari platformaga bog'langan — adapter almashganda aynan ular buziladi.
  • Fastify tana parseri, bo'sh JSON va listen manzilida Express'dan farq qiladi — testlar shu farqlarni ushlashi kerak.
  • Kanon o'lchovi: Fastify ~1.5× Express; Nest qatlami ~4–18 % narx; Nest+Fastify toza Express'dan tez.
  • vazifalar-api Express'da qoldi: kod Express'ga bog'langan, bazali endpoint'larda farq kichik; ishga tushish vaqti raqami — tartib xatosi.

Keyingi dars: Monorepo, standalone ilova va CLI buyruqlar — HTTP'siz Nest: o'sha modullar va DI bilan terminal buyrug'i yozamiz.

Manbalar

  • NestJS hujjati — Performance (Fastify): https://docs.nestjs.com/techniques/performance
  • Fastify hujjati — Server options (bodyLimit, logger), Content-Type parser: https://fastify.dev/docs/latest/Reference/Server/
  • Kanon (IlmHamroh, 2026-10-28): besh server o'lchovi (@nestjs/platform-fastify 12.2.0, fastify 5.12.7, autocannon), Express vs Nest Postgres o'lchovi. Ikki adapterdagi oltita so'rov tajribasi — biz ishga tushirdik (2026-11-02, NestJS 12.2.0, fastify 5.12.7, Node 24.21.0).
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
Fastify adapter bilan NestJS: FastifyAdapter, farqlar va o'lchov — IlmHamroh