NestJS Enterprise Backend APIs · Lezione

Repository TypeORM personalizzati

Crei repository personalizzati per incapsulare query complesse sul database e migliorare l'organizzazione e la riusabilità del codice.

Lezione 1 di 310 passaggi

Repository TypeORM personalizzati è una lezione NestJS Enterprise Backend APIs gratuita su CoddyKit. Questa è la lezione 1 di 3. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento NestJS Enterprise Backend APIs, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso NestJS Enterprise Backend APIs include 3 lezioni in totale.

Parti di questa lezione non sono ancora state tradotte e vengono mostrate in inglese.

Beyond Basic CRUD

TypeORM's default Repository offers basic operations like save, find, and delete. These are great for simple tasks.

However, real-world applications often need more complex queries or domain-specific data retrieval logic.

Encapsulating Complex Queries

Without custom repositories, complex database queries might end up directly in your service layer. This can make services bloated and harder to maintain.

  • Cleaner Services: Services focus on business logic, not database specifics.
  • Reusability: Complex queries can be reused across different parts of your application.
  • Testability: Easier to test database interactions in isolation.

Creating a Custom Repository

To create a custom repository, you define a class that extends TypeORM's Repository<Entity>. You must also decorate it with @EntityRepository(Entity) to link it to a specific entity.

import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  @Column({ unique: true })
  email: string;

  @Column({ default: true })
  isActive: boolean;
}

// src/user/user.repository.ts
import { EntityRepository, Repository } from 'typeorm';
import { User } from './user.entity';

@EntityRepository(User)
export class UserRepository extends Repository<User> {
  // Custom methods will go here
}

Injecting the Custom Repository

Once defined, you can inject your custom repository into NestJS services or controllers using the @InjectRepository() decorator.

Remember to pass your custom repository class as an argument to @InjectRepository().

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { UserRepository } from './user.repository';
import { User } from './user.entity';

@Injectable()
export class UserService {
  constructor(
    @InjectRepository(UserRepository)
    private userRepository: UserRepository,
  ) {}

  async findAllActive(): Promise<User[]> {
    // This method will be defined in the custom repo
    return this.userRepository.findActiveUsers();
  }
}

Adding a Custom Method

Inside your custom repository, you can add methods that encapsulate specific query logic. These methods can use the default Repository methods or TypeORM's Query Builder.

Let's add methods to find all active users and find a user by email.

// src/user/user.repository.ts (updated)
import { EntityRepository, Repository } from 'typeorm';
import { User } from './user.entity';

@EntityRepository(User)
export class UserRepository extends Repository<User> {
  async findActiveUsers(): Promise<User[]> {
    return this.find({ isActive: true });
  }

  async findByEmail(email: string): Promise<User | undefined> {
    return this.findOne({ email });
  }
}

Custom Repo Workflow

Here's the typical flow: you define your Entity, then your Custom Repository extending Repository<Entity>, and finally inject it into your Service.

// 1. user.entity.ts
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
@Entity() export class User {
  @PrimaryGeneratedColumn() id: number;
  @Column() name: string;
  @Column({ unique: true }) email: string;
  @Column({ default: true }) isActive: boolean;
}

// 2. user.repository.ts
import { EntityRepository, Repository } from 'typeorm';
import { User } from './user.entity';
@EntityRepository(User)
export class UserRepository extends Repository<User> {
  async findActiveUsers(): Promise<User[]> {
    return this.find({ isActive: true });
  }
}

// 3. user.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { UserRepository } from './user.repository';
import { User } from './user.entity';
@Injectable()
export class UserService {
  constructor(
    @InjectRepository(UserRepository)
    private userRepository: UserRepository,
  ) {}
  async getAllActive(): Promise<User[]> {
    return this.userRepository.findActiveUsers();
  }
}

Module Configuration

For NestJS to properly manage the TypeORM repositories, your module needs to import TypeOrmModule.forFeature() with your entities. The @EntityRepository decorator handles the TypeORM-side registration, allowing injection.

// src/user/user.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './user.entity';
import { UserService } from './user.service';
import { UserController } from './user.controller';

@Module({
  imports: [
    TypeOrmModule.forFeature([User]) // Only entities here
  ],
  providers: [UserService, UserController],
  exports: [UserService] // Export service if used elsewhere
})
export class UserModule {}

Leveraging Query Builder

For more complex queries, custom repositories often use TypeORM's powerful Query Builder. This allows you to construct dynamic queries with joins, conditions, and more.

Let's add a method to find users who are active and have a specific name pattern.

// src/user/user.repository.ts (extended)
import { EntityRepository, Repository } from 'typeorm';
import { User } from './user.entity';
import { MoreThan } from 'typeorm'; // Example for complex query

@EntityRepository(User)
export class UserRepository extends Repository<User> {
  async findActiveUsers(): Promise<User[]> {
    return this.find({ isActive: true });
  }

  async findByNamePattern(pattern: string): Promise<User[]> {
    return this.createQueryBuilder('user')
      .where('user.name LIKE :pattern', { pattern: `%${pattern}%` })
      .andWhere('user.isActive = :isActive', { isActive: true })
      .getMany();
  }
}

Check Your Understanding

Consider the following custom repository and service:

// product.repository.ts
import { EntityRepository, Repository, MoreThan } from 'typeorm';
import { Product } from './product.entity'; // Assume Product entity exists

@EntityRepository(Product)
export class ProductRepository extends Repository<Product> {
  async findAvailableProducts(): Promise<Product[]> {
    return this.find({ where: { stock: MoreThan(0), isActive: true } });
  }
}

// product.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { ProductRepository } from './product.repository';
import { Product } from './product.entity'; // Assume Product entity exists

@Injectable()
export class ProductService {
  constructor(
    @InjectRepository(ProductRepository)
    private productRepo: ProductRepository,
  ) {}

  async getProducts(): Promise<Product[]> {
    return this.productRepo.findAvailableProducts();
  }
}

Custom Repositories Summary

In this lesson, we explored custom TypeORM repositories. We learned that they are a powerful pattern to:

  • Encapsulate complex, reusable database query logic.
  • Keep your NestJS services clean and focused on business rules.
  • Improve code organization, reusability, and testability.

By extending TypeORM's Repository and using @EntityRepository, you can define domain-specific methods that make your data access layer much more robust.

Gratis per iniziare

Impara TypeScript con un tutor IA — gratis

Scrivi ed esegui vero codice nel tuo browser, ricevi aiuto istantaneo da un tutor IA disponibile 24/7, e riprendi da dove hai lasciato sul web o nell'app.

Corsi
20
Lezioni
76

Domande Frequenti

La lezione «Repository TypeORM personalizzati» è gratuita?

Sì — il testo completo di «Repository TypeORM personalizzati» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso NestJS Enterprise Backend APIs, passa a CoddyKit PRO. Il corso NestJS Enterprise Backend APIs include 3 lezioni in totale.

Cosa imparerò in «Repository TypeORM personalizzati»?

Crei repository personalizzati per incapsulare query complesse sul database e migliorare l'organizzazione e la riusabilità del codice. Eserciti NestJS Enterprise Backend APIs con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare NestJS Enterprise Backend APIs?

Non è richiesta alcuna esperienza precedente. NestJS Enterprise Backend APIs su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 3.

Quanto tempo richiede la lezione «Repository TypeORM personalizzati»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione NestJS Enterprise Backend APIs?

Sì. Ogni lezione NestJS Enterprise Backend APIs include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Repository TypeORM personalizzati
  2. Transazioni e migrazioni
  3. Popolamento e test del database
← Torna a NestJS Enterprise Backend APIs