IlmHamroh
JavaScript Full-stack/30-qism. NestJS32/65-dars13 daqiqa
Mundarija (25)

TypeORM bilan NestJS: TypeOrmModule, forFeature va @InjectRepository

Qisqacha: @nestjs/typeorm — TypeORM uchun rasmiy Nest moduli. TypeOrmModule.forRootAsync({ inject: [ConfigService], useFactory }) ulanishni (DataSource) yaratadi, TypeOrmModule.forFeature([VazifaEntity]) shu entity uchun repository provider'ini ro'yxatga qo'yadi, xizmat esa uni @InjectRepository(VazifaEntity) repo: Repository<VazifaEntity> bilan oladi. Dekoratorli entity Nest build'i bilan muammosiz ishlaydi. Tuzoqlar: synchronize: true prodakshnda ma'lumotni buzishi mumkin, bigint ustun esa string bo'lib keladi.

Bu darsda

  • TypeOrmModule.forRootAsync va forFeature bilan TypeORM'ni Nest'ga ulaysiz.
  • @InjectRepository tokeni qanday nomlanishini haqiqiy chiqish bilan ko'rasiz.
  • DataSource ni inject qilish, autoLoadEntities va ikkinchi ulanish (nomlangan DataSource) ni bilasiz.
  • synchronize va migratsiyalar farqini, bigint → string tuzog'ini tushuntirasiz.
  • Kanon tajribasidagi o'lchovni o'qib, TypeORM nega loyihaga kirmaganini bilasiz.

Oldin bilishingiz kerak: TypeORM, ORM tanlash qo'llanmasi, Dynamic modullar, @nestjs/config, Prisma bilan NestJS.

O'tgan darsda Prisma'ni Nest'ga o'zimiz ulagan edik — PrismaService va PrismaModule ni qo'lda yozdik. TypeORM uchun bu ishni rasmiy modul qiladi.

1. Nega bu kerak?

27-qismda TypeORM'ni ko'rgandik (TypeORM): @Entity, @Column dekoratorlari bilan klass yoziladi, DataSource yaratiladi, dataSource.getRepository(Vazifa) bilan repository olinadi. O'shanda bir muammoga duch kelgandik: Node'ning type stripping'i dekoratorlarni bajara olmaydi — TypeORM entity'si build'siz ishlamadi.

Nest'da bu muammo yo'q: loyiha baribir nest build bilan yig'iladi, dekorator metama'lumoti tayyor (Nest CLI va loyiha tuzilmasi). Kanon tajribasi buni alohida qayd etgan: dekoratorli entity build bilan ishladi.

Qolgan savol — DI. DataSource bitta bo'lishi, ilova ko'tarilganda ulanishi, yopilganda yopilishi kerak. Har xizmatga kerakli repository yetib borishi kerak. @nestjs/typeorm aynan shu ishni oladi.

O'xshatish: kutubxona. DataSource — kutubxona binosi, repository — har bir bo'lim (tarix, fizika). forRoot binoni ochadi, forFeature modulga "menga fizika bo'limining kaliti kerak" deydi, @InjectRepository esa o'sha kalitni xizmat qo'liga beradi.

2. Ulanish: forRoot va forRootAsync

2.1 Eng sodda shakl

ts
TypeOrmModule.forRoot({
  type: "postgres",
  url: "postgres://postgres@127.0.0.1:5432/bahor",
  entities: [VazifaEntity],
  synchronize: false,
})

Bu ishlaydi, lekin ulanish satri kodda qotib qolgan. @nestjs/config darsida ko'rgan qoida: sozlama — config'dan.

2.2 forRootAsync + ConfigService

ts
TypeOrmModule.forRootAsync({
  inject: [ConfigService],
  useFactory: (c: ConfigService) => ({
    type: "postgres",
    url: c.getOrThrow<string>("DATABASE_URL"),
    autoLoadEntities: true,
    synchronize: false,
  }),
})

Bu — Nest hujjatidagi naqsh; uni @nestjs/config darsida "boshqa modulga sozlama berish" deb ko'rgandik. useFactory ning natijasi — TypeORM'ning DataSource sozlamalari. Nest ConfigService ni yaratadi, fabrikani chaqiradi, DataSource ni ishga tushiradi va ilova yopilganda destroy() qiladi. Lifecycle ishini o'zingiz yozmaysiz — PrismaService dan farqi shu.

autoLoadEntities: true — entities ro'yxatini qo'lda yozmaslik: har forFeature([...]) dagi entity avtomatik qo'shiladi. Katta loyihada qulay — entity o'z moduli bilan birga turadi.

2.3 Kanon tajribasidagi ulanish

Kanon tajribasi config'siz, qisqa yozilgan (telefon uchun bo'lindi):

ts
@Module({
  imports: [
    TypeOrmModule.forRootAsync({
      useFactory: () => ({
        type: "postgres", url: URL, entities: [VazifaEntity],
        synchronize: false, extra: { max: 5 },
      }),
    }),
    TypeOrmModule.forFeature([VazifaEntity]),
  ],
  providers: [TypeormOmbor],
})
class M {}

extra — sozlamalar to'g'ridan pg drayveriga o'tadi: max: 5 — hovuz (pool) hajmi (Connection pooling).

3. Entity va repository

3.1 Entity

ts
@Entity({ name: "vazifalar" })
class VazifaEntity {
  @PrimaryColumn({ type: "bigint" }) id!: string;
  @Column({ name: "egasi_id", type: "bigint" }) egasiId!: string;
  @Column() matn!: string;
  @Column() bajarildi!: boolean;
  @Column() tartib!: number;
  @Column({
    name: "ochirilgan_vaqt", type: "timestamptz", nullable: true,
  })
  ochirilganVaqt!: Date | null;
}

Entity 26-qismdagi vazifalar jadvaliga moslangan: name — bazadagi ustun nomi, TypeScript'da esa egasiId. ! — "qiymatni TypeORM qo'yadi" (Klasslar TypeScript'da).

Diqqat qiling: id va egasiId — string. Sabab pastda, «bigint tuzog'i» bo'limida.

3.2 Repository'ni olish

ts
@Injectable()
class TypeormOmbor {
  constructor(
    @InjectRepository(VazifaEntity)
    private readonly repo: Repository<VazifaEntity>,
  ) {}
  royxat() {
    return this.repo.find({
      where: { egasiId: "1", ochirilganVaqt: IsNull() },
      order: { tartib: "ASC", id: "ASC" },
      take: 50,
    });
  }
}

@InjectRepository(VazifaEntity) — oddiy @Inject(token) ning qisqa shakli. Qaysi token? Demo loyihada tekshirdik (biz ishga tushirdik: @nestjs/typeorm 12.0.2, typeorm 1.1.2):

text
getRepositoryToken(VazifaEntity)              → VazifaEntityRepository
getRepositoryToken(VazifaEntity, "ikkinchi")  → ikkinchi_VazifaEntityRepository
getDataSourceToken("ikkinchi")                → ikkinchiDataSource

Ya'ni token — oddiy satr: entity nomi + Repository. forFeature([VazifaEntity]) shu nomli provider'ni ro'yxatga qo'yadi. Unutsangiz — Modullar darsidagi tanish xato: Nest can't resolve dependencies of the TypeormOmbor (?)… argument "VazifaEntityRepository" at index [0]…. Xabardagi satr nomidan qaysi forFeature yetishmayotganini bilasiz.

Butun zanjir bitta rasmda:

flowchart LR
  C["ConfigService"] --> F["forRootAsync: useFactory"]
  F --> DS["DataSource (ulanish)"]
  DS --> R["forFeature: VazifaEntityRepository"]
  R --> O["TypeormOmbor (@InjectRepository)"]
  O --> X["VazifalarService"]

Chapdan o'ngga: config'dan sozlama, sozlamadan ulanish, ulanishdan repository, repository'dan ombor. Har strelka — DI: bog'lanishni Nest o'zi quradi, siz faqat inject va dekoratorlarni yozasiz. Zanjirning biror halqasi yo'q bo'lsa, ilova ishga tushishda to'xtaydi va xabarda aynan qaysi token topilmagani yoziladi.

3.3 DataSource ni olish

Ba'zan repository emas, butun ulanish kerak: xom SQL, tranzaksiya, migratsiya holati. Sukut ulanishi uchun token — DataSource klassining o'zi:

ts
constructor(private readonly ds: DataSource) {}
// ...
await this.ds.query("SELECT 1");

Ikkinchi ulanish (masalan, faqat o'qish uchun replika) kerak bo'lsa — forRootAsync({ name: "ikkinchi", ... }), keyin @InjectDataSource("ikkinchi") va @InjectRepository(VazifaEntity, "ikkinchi"). Tokenlar — yuqoridagi ikkinchiDataSource va ikkinchi_VazifaEntityRepository.

Tekshirib ko'ring: VazifalarModule da forFeature([VazifaEntity]) bor. EksportModule dagi xizmat ham @InjectRepository(VazifaEntity) so'radi. Ishlaydimi?

Javob

Yo'q — Nest can't resolve dependencies … VazifaEntityRepository … in the EksportModule module. forFeature provider'ni faqat o'z modulida ro'yxatga qo'yadi. Ikki yo'l: EksportModule ham forFeature([VazifaEntity]) qiladi (repository bitta DataSource dan, nusxa muammo emas) yoki VazifalarModule TypeOrmModule ni qayta eksport qiladi (Modullar).

4. Natija va o'lchov

Kanon tajribasi namuna bazasidan (26–27-qism ma'lumoti, Aziz — id 1) royxat() ni 100 marta chaqirdi. Xuddi shu so'rov — Drizzle va Kysely bilan ham (keyingi ikkinchi dars). Kanon chiqishi (kanon o'lchovi, IlmHamroh, 2026-10, NestJS 12.2.0; uzun qatorlar kanon yozuvining o'zida kesilgan). Har qatordan uch narsani oling: mediana vaqt, id turi va birinchi qatorning shakli:

text
kontekst (TypeORM ulanishi bilan): 79 ms
TypeORM (Repository.find): 12 qator, mediana 2.18 ms; id turi: string; birinchisi: {"id":"1","egasiId":"1","matn":"JavaScript kursining 26-qismini boshlash #o'qish","bajarildi":false,"tartib":1
Drizzle: 12 qator, mediana 2.36 ms; id turi: number; birinchisi: {"id":1,"egasiId":1,"matn":"JavaScript kursining 26-qismini boshlash #o'qish","bajarildi":false,"tartib":1,"oc
Kysely: 12 qator, mediana 2.49 ms; id turi: string; birinchisi: {"id":"1","matn":"JavaScript kursining 26-qismini boshlash #o'qish","bajarildi":false,"tartib":1}
Bir xil so'rov (12 qator), mediana
  • TypeORM2,18 ms
  • Drizzle2,36 ms
  • Kysely2,49 ms

Manba: Kanon o'lchovi, IlmHamroh, 2026-10: NestJS 12.2.0, 100 marta, bitta mashina

Grafikda farq ko'rinadi, lekin u ahamiyatsiz: 0.3 ms — bazaga tarmoq aylanishining (round trip) bir qismi. 100 ta o'lchov, bitta mashina, boshqa jarayonlar bilan bir vaqtda. Shu sharoitda "TypeORM eng tez" degan xulosa chiqarib bo'lmaydi. Kanon xulosasi: uchalasi bir xil — tanlov tezlik bo'yicha emas, qulaylik va turlar bo'yicha.

Kontekst 79 ms — ilova ko'tarilishiga TypeORM ulanishi qo'shgan vaqt (metama'lumot yig'ish + birinchi ulanish).

5. bigint tuzog'i

Natijadagi id turi: string ga qayting. 26-qismda vazifalar.id — bigint (8 bayt) ustun. JavaScript number i faqat 2⁵³ gacha butun sonlarni aniq saqlaydi (Number turi). pg drayveri xavfsizlik uchun bigint ni satr qilib beradi. TypeORM uni o'zgartirmaydi: entity'da id!: string.

Natija: vazifa.id === 1 — false (chunki "1"). JSON javobda "id": "1" — API shartnomasida id son edi (REST prinsiplari). Har ombor buni o'zicha hal qiladi:

Kutubxona id turi Qanday
TypeORM string sukut; transformer bilan o'zgartiriladi
Drizzle number bigint("id", { mode: "number" })
Kysely string sukut
Kanon PgOmbori number pg turlar xaritasi (26-qism)

Kanon PgOmbori 26-qismda bu muammoni pg darajasida yechgan (pgPool() bigint ni Number qiladi). Prisma esa JavaScript'ning bigint turini qaytaradi — PrismaOmbori uni API uchun o'zi Number ga aylantiradi, xavfsiz butun son tekshiruvi bilan (o'tgan dars). Natijada mijoz qaysi ombor ishlayotganidan qat'iy nazar "id": 1 (son) oladi.

6. synchronize va migratsiyalar

synchronize: true — TypeORM ishga tushishda entity'larni bazaga solishtiradi va farqni o'zi tuzatadi: yangi ustun qo'shadi, keraksizini o'chiradi. Lokal tajribada qulay. Prodakshnda xavfli: entity'da maydon nomini o'zgartirsangiz, TypeORM eski ustunni ma'lumoti bilan o'chirib, yangisini bo'sh yaratishi mumkin.

To'g'ri yo'l — migratsiyalar (Prisma Migrate chuqur darsidagi tamoyil): typeorm migration:generate o'zgarish SQL'ini faylga yozadi, siz uni o'qib chiqasiz, deploy paytida qo'llaysiz. TypeORM CLI uchun alohida DataSource fayli kerak (Nest modulidan tashqarida). Bu oqimni biz sinamadik — hujjat bo'yicha (2026-11). Kanonda sxema manbai — 26–27-qismdagi SQL migratsiyalar.

Diqqat: Kanon tajribasida synchronize: false turibdi va bu tasodif emas: tajriba 26-qismdagi haqiqiy jadvalga ulanadi. true bo'lganda TypeORM entity'da yo'q ustunlarni (yaratilgan_vaqt, versiya, qidiruv …) o'chirishga urinardi.

7. Kanon qarori: TypeORM loyihaga kirmadi

TypeORM Kanon (pg + Prisma)
Nest moduli rasmiy, qulay OmborModule (o'zimiz)
Turlar entity klassi Prisma generatsiyasi / qo'lda
bigint string API'da number (pg — turlar xaritasi, Prisma — omborda aylantirish)
Tezlik teng teng

27-qismda ORM tanlovi qilingan edi (ORM tanlash qo'llanmasi): kanon pg va Prisma'da qoldi, TypeORM — tajriba. 30-qism bu qarorni o'zgartirmaydi: Nest'ga ko'chishdan maqsad — freymvork almashtirish, ma'lumot qatlamini qayta yozish emas. Ikkalasini bir vaqtda o'zgartirish xatoni qidirishni ikki barobar qiyinlashtiradi.

Nima yutildi: TypeORM'ning Nest bilan eng yaxshi ishlashini — rasmiy modul, forFeature, lifecycle — o'lchov bilan ko'rdik. Agar yangi Nest loyihasini TypeORM bilan boshlasangiz, shu darsdagi naqsh to'liq yetarli.

8. Express'da qanday edi, Nest'da qanday

27-qismda TypeORM'ni Express'siz, oddiy skriptda sinagandik. Uni Express ilovasiga qo'shsak, uch ishni o'zimiz qilardik: new DataSource(...) va await ds.initialize() — server.ts da; repository'ni ds.getRepository(Vazifa) bilan olib, omborga parametr qilib berish; to'xtashda ds.destroy() ni chaqirish.

Ish Express Nest + @nestjs/typeorm
Ulanish initialize() qo'lda forRootAsync
Repository getRepository + parametr forFeature + @InjectRepository
Yopish destroy() qo'lda modul o'zi
Entity build type stripping yiqiladi nest build — ishlaydi

Rasmiy modul bu uch ishning hammasini oladi va yozuvni qisqartiradi. To'lov — bitta qo'shimcha paket va "sehr": token satri qayerdan kelgani ko'rinmaydi. Shuning uchun «Repository'ni olish» bo'limidagi token tajribasi foydali — sehr ochilsa, xato xabarini o'qish oson.

9. Hujumchi nigohi

TypeORM'da parametr berishning xavfsiz va xavfli yo'llari yonma-yon turadi:

ts
// ✅ parametr: qiymat alohida yuboriladi
this.repo.createQueryBuilder("v")
  .where("v.matn = :matn", { matn })
  .getMany();
// ❌ satr birlashtirish: SQL injection
this.repo.createQueryBuilder("v")
  .where("v.matn = '" + matn + "'")
  .getMany();

Ikkinchi variantda matn ga x' OR '1'='1 yuborilsa, shart doim rost bo'ladi va hamma qatorlar qaytadi — 26-qismdagi parametrli so'rov qoidasining o'zi (Parametrli SQL). Yana bir xavf — find({ where: req.query }): mijoz yuborgan obyekt to'g'ridan-to'g'ri filtrga tushadi va u istalgan ustun bo'yicha qidiradi (masalan, boshqa egasining vazifalari). Kanonda filtrlar Zod sxemasidan o'tadi va faqat ruxsat etilgan maydonlar omborga yetadi (Validatsiya).

10. Ko'p uchraydigan xatolar

Belgi Sabab Davosi
… argument "VazifaEntityRepository" at index [0] forFeature yo'q modulga TypeOrmModule.forFeature([VazifaEntity])
EntityMetadataNotFoundError entity entities da yo'q autoLoadEntities: true yoki ro'yxatga qo'shing
Ustun yo'qoldi, ma'lumot ketdi prodakshnda synchronize: true false + migratsiyalar
id === 1 — false bigint → string transformer yoki o'z turlaringiz
Ulanish satri kodda forRoot qotib qolgan forRootAsync + ConfigService

11. Mashqlar

Mashqlar kurs/mashqlar/30/32-typeorm-nestjs/ da.

1-mashq (oson): token va sozlama

To'ldiring:

  • @InjectRepository(Buyurtma) tokeni —
  • Entity'larni forFeature dan avtomatik yig'ish sozlamasi —
  • Prodakshnda synchronize qiymati —
  • Kanon tajribasida TypeORM id turi —
Yechim
  • BuyurtmaRepository — entity nomi + Repository (demo chiqishi).
  • autoLoadEntities — entities ro'yxatini qo'lda yozmaslik.
  • false — sxema migratsiyalar bilan o'zgaradi.
  • string — pg bigint ni satr qiladi.

2-mashq (o'rta): forFeature modeli

Kichik model yozing. getRepositoryToken(entity, ulanish) — ulanish berilmasa ${entity.name}Repository, berilsa ${ulanish}_${entity.name}Repository. forFeature(entitylar, ulanish) — provider'lar massivini qaytarsin: { provide: token, entity: nomi }. Keyin modulda(provider'lar, token) — token topilsa entity nomini, topilmasa Nest uslubidagi xato matnini qaytarsin. Ishora: klassning name xususiyati (Funksiya obyekt sifatida).

Yechim
js
class VazifaEntity {}
class IzohEntity {}

function getRepositoryToken(entity, ulanish) {
  const asos = `${entity.name}Repository`;
  return ulanish === undefined ? asos : `${ulanish}_${asos}`;
}

function forFeature(entitylar, ulanish) {
  return entitylar.map((e) => ({
    provide: getRepositoryToken(e, ulanish),
    entity: e.name,
  }));
}

function modulda(providerlar, token) {
  const p = providerlar.find((x) => x.provide === token);
  return p?.entity
    ?? `Nest can't resolve dependencies: "${token}" topilmadi`;
}

const vazifalarModuli = forFeature([VazifaEntity]);
const replika = forFeature([VazifaEntity], "ikkinchi");
console.log(getRepositoryToken(VazifaEntity));
console.log(replika[0].provide);
console.log(modulda(vazifalarModuli, "VazifaEntityRepository"));
console.log(modulda(vazifalarModuli,
  getRepositoryToken(IzohEntity)));

Konsolda:

text
VazifaEntityRepository
ikkinchi_VazifaEntityRepository
VazifaEntity
Nest can't resolve dependencies: "IzohEntityRepository" topilmadi

Birinchi ikki qator demo loyihadagi haqiqiy getRepositoryToken natijasi bilan bir xil. Oxirgisi — forFeature ga IzohEntity qo'shilmagan modul. Model soddalashtirilgan: haqiqiy provider'da useFactory bor, u DataSource dan getRepository(entity) qaytaradi.

3-mashq (qiyin): bigint ni xavfsiz aylantirish

idOl(qiymat) yozing: pg dan kelgan satr id ni oladi. Agar son Number.MAX_SAFE_INTEGER dan oshmasa — number, oshsa — BigInt qaytarsin; raqam bo'lmagan satr uchun TypeError("id: butun son kutilgan") tashlasin. Keyin bu funksiyani TypeORM transformer'i shaklida o'rang: { from: idOl, to: (x) => String(x) }. Ishora: BigInt(x) <= BigInt(Number.MAX_SAFE_INTEGER) (Number turi).

Yechim
js
function idOl(qiymat) {
  if (!/^\d+$/.test(qiymat)) {
    throw new TypeError("id: butun son kutilgan");
  }
  const katta = BigInt(qiymat);
  return katta <= BigInt(Number.MAX_SAFE_INTEGER)
    ? Number(katta)
    : katta;
}

const transformer = { from: idOl, to: (x) => String(x) };

console.log(transformer.from("1"), typeof transformer.from("1"));
console.log(transformer.from("9007199254740991"));
console.log(transformer.from("9007199254740993"));
console.log(transformer.to(42));
try {
  transformer.from("12a");
} catch (e) {
  console.log(`${e.name}: ${e.message}`);
}

Konsolda:

text
1 number
9007199254740991
9007199254740993n
42
TypeError: id: butun son kutilgan

Uchinchi qator — n qo'shimchasi: bu BigInt. Agar uni oddiy Number qilsak, 9007199254740993 → 9007199254740992 bo'lardi — boshqa yozuvning id si. TypeORM'da @PrimaryColumn({ type: "bigint", transformer }) — entity'da id endi son. Lekin JSON.stringify BigInt ni bilmaydi — javobga chiqarishdan oldin satrga aylantirish kerak bo'ladi.

12. Loyiha qadami: o'zgarish yo'q — va nega

vazifalar-api o'zgarmaydi. TypeORM kanonda faqat tajriba: rasmiy modul bilan ulanish, forFeature va @InjectRepository ishladi, tezlik pg va Prisma bilan teng. Loyiha 27-qismdagi ORM tanlovida qoladi («Kanon qarori» bo'limi).

O'z o'quv loyihangizda sinab ko'rmoqchi bo'lsangiz — alohida tarmoq (branch) oching va VazifaOmbori interfeysini TypeORM bilan amalga oshiring. 27-qismdagi shartnoma testlari (Repository va SQL'ni testlash) sizga "to'g'ri ishlayaptimi" degan savolga javob beradi — Repository naqshi va qatlamlar darsida bu g'oyaga qaytamiz.

13. Real ishda

  • TypeORM + Nest — eng keng tarqalgan juftliklardan biri; ko'p korporativ loyihalar va qo'llanmalar shu bilan. forFeature va @InjectRepository ni o'qiy olish shart.
  • synchronize: true prodakshnda — haqiqiy hodisalar sababi; review'da birinchi tekshiriladigan qator.
  • Relations va N+1: find({ relations: ["izohlar"] }) — bitta JOIN; har vazifa uchun alohida so'rov esa N+1 (N+1 muammosi). Nest bunga ta'sir qilmaydi — muammo ORM darajasida, shuning uchun 26–27-qismdagi bilim Nest'da ham aynan kerak.
  • Migratsiyalar deploy'da: typeorm migration:run — alohida qadam; ilova ichidagi migrationsRun: true qulay, lekin bir nechta nusxa bir vaqtda ishga tushsa, migratsiya ikki marta boshlanishi mumkin. Kanon 27-qismdan beri boshqacha qiladi: ilova faqat tekshiradi (migratsiya orqada qolsa — prodakshnda ishga tushmaydi), qo'llash — npm run db:migrate.
  • Ikkinchi DataSource — o'qish replikasi yoki eski tizim bazasi uchun (Read replica'lar — keyingi qismda).
  • Intervyu: "forRoot va forFeature farqi?", "@InjectRepository qanday ishlaydi?", "nega synchronize ni prodakshnda o'chirasiz?".

Xulosa

  • TypeOrmModule.forRootAsync — ulanish (DataSource), config'dan; lifecycle'ni modul o'zi boshqaradi.
  • forFeature([Entity]) — modulga repository provider'i; token — EntityRepository satri.
  • @InjectRepository(Entity) — Repository<Entity>; butun ulanish — DataSource; ikkinchi ulanish — nom bilan.
  • Dekoratorli entity Nest build'i bilan ishlaydi (type stripping muammosi yo'q).
  • synchronize: true faqat lokal; prodakshnda — migratsiyalar.
  • bigint → string: transformer yoki o'z turlaringiz; kanon tajribasida TypeORM, Drizzle, Kysely tezligi teng.

Keyingi dars: Mongoose bilan NestJS — @Schema, @Prop, SchemaFactory va @InjectModel bilan dekoratorli Mongo sxemalari.

Manbalar

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
TypeORM bilan NestJS: TypeOrmModule, forFeature va @InjectRepository — IlmHamroh