Usullar4 min read

Model-View-Controller

Nest default holatda ichki qismda Express kutubxonasidan foydalanadi. Shuning uchun Expressda MVC (Model-View-Controller) patternini qo'llashning barcha usullari Nestga ham tegishl

Nest default holatda ichki qismda Express kutubxonasidan foydalanadi. Shuning uchun Expressda MVC (Model-View-Controller) patternini qo'llashning barcha usullari Nestga ham tegishli.

Avval CLI vositasi yordamida oddiy Nest ilovasini scaffold qilamiz:

Terminal
1$ npm i -g @nestjs/cli
2$ nest new project

MVC ilova yaratish uchun HTML ko'rinishlarni render qilishda template engine ham kerak bo'ladi:

Terminal
1$ npm install --save hbs

Biz hbs (Handlebars) engine dan foydalandik, ammo talablaringizga mos keladiganini tanlashingiz mumkin. O'rnatish jarayoni tugagach, quyidagi kod yordamida express instansiyasini sozlashimiz kerak:

TypeScript
main
1import { NestFactory } from '@nestjs/core';
2import { NestExpressApplication } from '@nestjs/platform-express';
3import { join } from 'node:path';
4import { AppModule } from './app.module';
5
6async function bootstrap() {
7  const app = await NestFactory.create<NestExpressApplication>(
8    AppModule,
9  );
10
11  app.useStaticAssets(join(__dirname, '..', 'public'));
12  app.setBaseViewsDir(join(__dirname, '..', 'views'));
13  app.setViewEngine('hbs');
14
15  await app.listen(process.env.PORT ?? 3000);
16}
17bootstrap();

Biz Express ga public direktoriyasi statik assetlarni saqlash uchun ishlatilishini, views esa shablonlarni o'z ichiga olishini va HTML chiqishini render qilish uchun hbs template engine ishlatilishini aytdik.

Template render qilish

Endi views direktoriyasini va uning ichida index.hbs shablonini yarating. Shablonda controllerdan uzatilgan message ni chiqaramiz:

Html
1<!DOCTYPE html>
2<html>
3  <head>
4    <meta charset="utf-8" />
5    <title>App</title>
6  </head>
7  <body>
8    {{ "{{ message }\}" }}
9  </body>
10</html>

Keyin app.controller faylini ochib, root() metodini quyidagi kod bilan almashtiring:

TypeScript
app.controller
1import { Get, Controller, Render } from '@nestjs/common';
2
3@Controller()
4export class AppController {
5  @Get()
6  @Render('index')
7  root() {
8    return { message: 'Hello world!' };
9  }
10}

Bu kodda @Render() dekoratorida ishlatiladigan shablonni ko'rsatamiz, va route handler metodining qaytargan qiymati render qilish uchun shablonga uzatiladi. Qaytish qiymati message xossasiga ega obyekt ekaniga e'tibor bering, bu shablonda yaratgan message placeholderiga mos keladi.

Ilova ishga tushib turgan paytda brauzeringizni ochib http://localhost:3000 manziliga o'ting. Siz Hello world! xabarini ko'rasiz.

Dinamik template render qilish

Agar ilova mantiqi qaysi shablon render qilinishini dinamik tarzda hal qilishi kerak bo'lsa, @Render() dekoratori o'rniga @Res() dekoratoridan foydalanishimiz va view nomini route handlerda berishimiz kerak:

Hint

Nest @Res() dekoratorini aniqlaganda, u kutubxonaga xos response obyektini inject qiladi. Biz bu obyektdan shablonni dinamik render qilish uchun foydalanishimiz mumkin. response obyektining API si haqida batafsil bu yerda o'qing.

TypeScript
app.controller
1import { Get, Controller, Res, Render } from '@nestjs/common';
2import { Response } from 'express';
3import { AppService } from './app.service';
4
5@Controller()
6export class AppController {
7  constructor(private appService: AppService) {}
8
9  @Get()
10  root(@Res() res: Response) {
11    return res.render(
12      this.appService.getViewName(),
13      { message: 'Hello world!' },
14    );
15  }
16}

Misol

Ishlaydigan misol bu yerda mavjud.

Fastify

Ushbu bobda aytilganidek, Nest bilan birga mos HTTP provayderidan foydalanishimiz mumkin. Shunday kutubxonalardan biri - Fastify. Fastify bilan MVC ilova yaratish uchun quyidagi paketlarni o'rnatishimiz kerak:

Terminal
1$ npm i --save @fastify/static @fastify/view handlebars

Keyingi qadamlar Expressda ishlatilgan jarayonga deyarli o'xshash, platformaga xos kichik farqlar bilan. O'rnatish jarayoni tugagach, main.ts faylini oching va uning tarkibini yangilang:

TypeScript
main
1import { NestFactory } from '@nestjs/core';
2import { NestFastifyApplication, FastifyAdapter } from '@nestjs/platform-fastify';
3import { AppModule } from './app.module';
4import { join } from 'node:path';
5
6async function bootstrap() {
7  const app = await NestFactory.create<NestFastifyApplication>(
8    AppModule,
9    new FastifyAdapter(),
10  );
11  app.useStaticAssets({
12    root: join(__dirname, '..', 'public'),
13    prefix: '/public/',
14  });
15  app.setViewEngine({
16    engine: {
17      handlebars: require('handlebars'),
18    },
19    templates: join(__dirname, '..', 'views'),
20  });
21  await app.listen(process.env.PORT ?? 3000);
22}
23bootstrap();

Fastify API da bir nechta farqlar bor, ammo bu metod chaqiriqlarining yakuniy natijasi bir xil. Muayyan farqlardan biri - Fastifydan foydalanganda @Render() dekoratoriga uzatiladigan shablon nomida fayl kengaytmasi ham bo'lishi kerak.

Buni quyidagicha sozlashingiz mumkin:

TypeScript
app.controller
1import { Get, Controller, Render } from '@nestjs/common';
2
3@Controller()
4export class AppController {
5  @Get()
6  @Render('index.hbs')
7  root() {
8    return { message: 'Hello world!' };
9  }
10}

Muqobil ravishda, @Res() dekoratoridan foydalanib response ni bevosita inject qilishingiz va render qilmoqchi bo'lgan view ni ko'rsatishingiz mumkin:

TypeScript
1import { Res } from '@nestjs/common';
2import { FastifyReply } from 'fastify';
3
4@Get()
5root(@Res() res: FastifyReply) {
6  return res.view('index.hbs', { title: 'Hello world!' });
7}

Ilova ishga tushib turgan paytda brauzeringizni ochib http://localhost:3000 manziliga o'ting. Siz Hello world! xabarini ko'rasiz.

Misol

Ishlaydigan misol bu yerda mavjud.