Retseptlar3 min read

SQL (Sequelize)

##### Bu bo'lim faqat TypeScript uchun

Bu bo'lim faqat TypeScript uchun

Warning Bu maqolada custom component'lar yordamida Sequelize package'i asosida DatabaseModule ni noldan qanday yaratish ko'rsatiladi. Natijada bu yondashuvda qo'shimcha overhead ko'p bo'ladi. Uni tayyor @nestjs/sequelize package'idan foydalanish orqali oldini olish mumkin. Ko'proq ma'lumot uchun bu yerga qarang.

Sequelize vanilla JavaScript'da yozilgan mashhur Object Relational Mapper (ORM) hisoblanadi. Bundan tashqari, asosiy sequelize uchun dekoratorlar va qo'shimcha imkoniyatlar beradigan sequelize-typescript TypeScript wrapper'i ham mavjud.

Boshlash

Bu kutubxona bilan ishlashni boshlash uchun quyidagi dependency'larni o'rnatishimiz kerak:

Terminal
1$ npm install --save sequelize sequelize-typescript mysql2
2$ npm install --save-dev @types/sequelize

Birinchi qadam sifatida constructor'ga options obyekt uzatib Sequelize instance yaratamiz. Shuningdek, barcha model'larni qo'shishimiz (modelPaths property'dan ham foydalanish mumkin) va database table'larini sync() qilishimiz kerak.

TypeScript
database.providers
1import { Sequelize } from 'sequelize-typescript';
2import { Cat } from '../cats/cat.entity';
3
4export const databaseProviders = [
5  {
6    provide: 'SEQUELIZE',
7    useFactory: async () => {
8      const sequelize = new Sequelize({
9        dialect: 'mysql',
10        host: 'localhost',
11        port: 3306,
12        username: 'root',
13        password: 'password',
14        database: 'nest',
15      });
16      sequelize.addModels([Cat]);
17      await sequelize.sync();
18      return sequelize;
19    },
20  },
21];
Hint

Best practice'ga amal qilib, custom provider'ni *.providers.ts suffix'iga ega alohida faylda e'lon qildik.

Keyin bu provider'larni ilovaning qolgan qismi uchun accessible qilish maqsadida export qilishimiz kerak.

TypeScript
1import { Module } from '@nestjs/common';
2import { databaseProviders } from './database.providers';
3
4@Module({
5  providers: [...databaseProviders],
6  exports: [...databaseProviders],
7})
8export class DatabaseModule {}

Endi Sequelize obyektini @Inject() dekoratori yordamida inject qila olamiz. Sequelize async provider'iga bog'liq bo'lgan har bir class Promise resolve bo'lguncha kutadi.

Model injection'i

Sequelize ichida Model database'dagi table'ni ifodalaydi. Bu class instance'lari esa database row'ni anglatadi. Avvalo bizga kamida bitta entity kerak:

TypeScript
cat.entity
1import { Table, Column, Model } from 'sequelize-typescript';
2
3@Table
4export class Cat extends Model {
5  @Column
6  name: string;
7
8  @Column
9  age: number;
10
11  @Column
12  breed: string;
13}

Cat entity cats direktoriyasiga tegishli. Bu direktoriyaning o'zi CatsModule ni ifodalaydi. Endi Repository provider yaratish vaqti keldi:

TypeScript
cats.providers
1import { Cat } from './cat.entity';
2
3export const catsProviders = [
4  {
5    provide: 'CATS_REPOSITORY',
6    useValue: Cat,
7  },
8];
Warning

Real loyihalarda magic string'lardan qochish kerak. CATS_REPOSITORY ham, SEQUELIZE ham alohida constants.ts faylida saqlangani ma'qul.

Sequelize'da ma'lumotlarni boshqarish uchun static metodlardan foydalaniladi, shu sabab bu yerda alias yaratdik.

Endi CATS_REPOSITORY ni @Inject() dekoratori orqali CatsService ichiga inject qila olamiz:

TypeScript
cats.service
1import { Injectable, Inject } from '@nestjs/common';
2import { CreateCatDto } from './dto/create-cat.dto';
3import { Cat } from './cat.entity';
4
5@Injectable()
6export class CatsService {
7  constructor(
8    @Inject('CATS_REPOSITORY')
9    private catsRepository: typeof Cat
10  ) {}
11
12  async findAll(): Promise<Cat[]> {
13    return this.catsRepository.findAll<Cat>();
14  }
15}

Database connection asynchronous, lekin Nest bu jarayonni oxirgi foydalanuvchi uchun deyarli sezilmas qiladi. CATS_REPOSITORY provider'i db connection tayyor bo'lguncha kutadi, CatsService esa repository ishlatishga tayyor bo'lguncha kechiktiriladi. Barcha class'lar instantiate qilingach, butun ilova ishga tushishi mumkin.

Yakuniy CatsModule quyidagicha bo'ladi:

TypeScript
cats.module
1import { Module } from '@nestjs/common';
2import { CatsController } from './cats.controller';
3import { CatsService } from './cats.service';
4import { catsProviders } from './cats.providers';
5import { DatabaseModule } from '../database/database.module';
6
7@Module({
8  imports: [DatabaseModule],
9  controllers: [CatsController],
10  providers: [
11    CatsService,
12    ...catsProviders,
13  ],
14})
15export class CatsModule {}
Hint

CatsModule ni root AppModule ichiga import qilishni unutmang.