Md. A. Apu
Md. A. Apu

Reputation: 1250

How to create custom (separate file) repository in NestJS 9 with TypeORM 0.3.x

This is not a duplicate Q. Please don't mark this as that.

Following is not I want

import { EntityRepository, Repository } from "typeorm";
import { Test } from "./test.model";
import { Injectable } from "@nestjs/common";

@EntityRepository(Test)
export class TestRepository extends Repository<Test> {}

the @EntityRepository decorator is now deprecated.

I also don't want to make a fake repository like in here: https://stackoverflow.com/a/73352265/5420070

Don't want this either as I've to extract manager from dataSource, I don't want this because I think this is not the best way.

    export const UserRepository = dataSource.getRepository(User).extend({
        //                        ^^^^^^^^^^ from where this came from
        findByName(firstName: string, lastName: string) {
            return this.createQueryBuilder("user")
                .where("user.firstName = :firstName", { firstName })
                .andWhere("user.lastName = :lastName", { lastName })
                .getMany()
        },
    })

Found above in: https://orkhan.gitbook.io/typeorm/docs/custom-repository#how-to-create-custom-repository

I don't think this is in NestJS context.

What I want Want to know right way to make custom repository in latest version of NestJS (v9) & TypeORM (v0.3). In @EntityRepository deprecation note, they said that need to extend the repo to create custom repo like someRepo.extend({}). I want to know how to do it in NestJS way

Upvotes: 9

Views: 6047

Answers (2)

A. Maitre
A. Maitre

Reputation: 3569

In order to achieve what you want, you could do something like the following.

This solution is inspired by the official NestJS docs related to this topic, with some customization.

Steps to achieve it:

  1. Create your TypeOrm entity as usual, let's say UserEntity (user.entity.ts file)
  2. Create a UserRepository class (user.repository.ts file)
  3. Create a UserService class as usual (user.service.ts file)
  4. Import the UserRepository into your UserService
  5. Update UserModule in order to provide the UserRepository and needed UserEntity

Detailed implementation example

1. user.entity.ts file

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

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

  @Column()
  firstName: string;

  @Column()
  lastName: string;

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

2. user.repository.ts file

import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { UserEntity } from './user.entity';

export class UserRepository extends Repository<UserEntity> {
    constructor(
        @InjectRepository(UserEntity)
        private userRepository: Repository<UserEntity>
    ) {
        super(userRepository.target, userRepository.manager, userRepository.queryRunner);
    }

    // sample method for demo purposes
    async findByEmail(email: string): Promise<UserEntity> {
        return await this.userRepository.findOneBy({ email }); // could also be this.findOneBy({ email });, but depending on your IDE/TS settings, could warn that userRepository is not used though. Up to you to use either of the 2 methods
    }
    
    // your other custom methods in your repo...
}

3. & 4. user.service.ts file

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

@Injectable()
export class UserService {
  constructor(
    private readonly userRepository: UserRepository, // import as usual
  ) {}

  findAll(): Promise<UserEntity[]> {
    return this.userRepository.find();
  }
  
  // call your repo method
  findOneByEmail(email: string): Promise<UserEntity> {
    return this.userRepository.findByEmail({ email });
  }

  findOne(id: number): Promise<UserEntity> {
    return this.userRepository.findOneBy({ id });
  }

  async remove(id: string): Promise<void> {
    await this.userRepository.delete(id);
  }
  
  // your other custom methods in your service...
}

5. Updating UserModule (user.module.ts file)

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

@Module({
  imports: [TypeOrmModule.forFeature([UserEntity])], // here we provide the TypeOrm support as usual, specifically for our UserEntity in this case
  providers: [UserService, UserRepository], // here we provide our custom repo
  controllers: [UserController],
  exports: [UserService, UserRepository] // add this only if you use service and/or custom repo within another module/service
})
export class UserModule {}

With this in place, you should be able to import the UserModule in your AppModule and be able to both implement custom methods in the UserRepository and use them in the UserService. You should also be able to call the manager and queryRunnner of the custom repository.

Additional Note

If you need to directly call your UserRepository methods from within another module/service, then update UserModule to export the UserRepository

Hope it helps, don't hesitate to comment.

Upvotes: 15

Kazi Akib Javed
Kazi Akib Javed

Reputation: 185

import { Column, Entity, JoinColumn, ManyToOne, OneToMany } from "typeorm";
import { CustomBaseEntity } from "../core/custom-base.entity";//custom-made
@Entity({name: 'rcon_log', schema: 'dbo'})
export class LogEntity extends CustomBaseEntity{
------------your code-----------
}

Upvotes: 0

Related Questions