NestJS with TypORM
NestJS is a popular framework for building scalable and efficient server-side applications using Node.js. It provides a modular structure for organizing your code and makes it easy to use various libraries and frameworks, such as TypeORM, for managing your database.
In TypeORM 0.2.x, it was easy to create a custom repository and use the @InjectRepository
and @EntityRepository
annotation to inject it into your NestJS service. However, in TypeORM 0.3, the API for creating custom repositories has changed, and the existing approach is no longer valid.
Custom repositories are a way to extend the Repository
class provided by TypeORM, which is a class that provides a set of common methods for interacting with a database. Custom repositories allow you to add custom methods or queries to the Repository
class, which can be useful if you want to reuse certain queries or add additional functionality.
In this article, we will look at how to create and use custom repositories in NestJS with TypeORM 0.3.
We will start by creating a custom repository interface and implementing it with custom methods. Then, we will inject the custom repository into a NestJS service and use it to access the custom methods. Finally, we will register the custom repository with a NestJS module to make it available for injection.
Creating a custom repository
To create a custom repository in TypeORM 0.3, you need to define an interface that extends the Repository
class. This interface should include any custom methods or queries that you want to use in your application.
Here’s an example of a custom repository interface for a User
entity:
user.repository.ts
import { Repository } from 'typeorm';
import { User } from './user.entity';
export interface UserRepository extends Repository<User> {
this: Repository<User>;
getUsers(): Promise<User[]>;
getUser(id: number): Promise<User>;
createUser(user: { firstName: string; lastName: string; isActive: boolean });
}
In this example, we’ve defined a UserRepository
interface that extends the Repository
class and includes three custom methods: getUsers
, getUser
, and createUser
.
To implement the custom repository interface, you can create an object with the custom methods as its properties. Here’s an example of how to implement the UserRepository
interface:
user.repository.ts
...
...
export const customUserRepository: Pick<UserRepository, any> = {
getUser(this: Repository, id) {
return this.findOne({ where: { id } });
},
getUsers(this: Repository) {
return this.find();
},
createUser(this: Repository, user) {
return this.save(user);
},
};
In this example, we’ve defined an object called customUserRepository
that has the same properties as the UserRepository
interface. Each property is a function that implements the corresponding method from the interface. Notice that we've used the this
keyword to refer to the current instance of the Repository
class. This allows us to use the Repository
class's methods, such as find
and save
, in our custom methods.
Injecting the custom repository into a NestJS service
To use the custom repository in a NestJS service, you need to inject it using the @InjectRepository
decorator and the custom repository interface.
Here’s an example of a NestJS service that injects the UserRepository
:
user.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './user.entity';
import { UserRepository } from './user.repository';
@Injectable()
export class UserService {
constructor( @InjectRepository(User) private readonly userRepository: UserRepository, ) {}
async getAll() {
return await this.userRepository.getUsers();
}
async createUser(): Promise<User> {
const user: User = this.userRepository.create();
user.firstName = 'john';
user.isActive = true;
user.lastName = 'doe';
return await this.userRepository.createUser(user);
}
}
In this example, we’ve injected the UserRepository
using the @InjectRepository
decorator and the User
symbol. We can then use the userRepository
property, which is an instance of the UserRepository
interface, to access the custom repository methods in our service.
Registering the custom repository with a NestJS module
To use the custom repository in your NestJS application, you need to register it with the module where it will be used.
Here’s an example of how to register the UserRepository
with a NestJS module:
user.module.ts
import { Module } from '@nestjs/common';
import {
getDataSourceToken,
getRepositoryToken,
TypeOrmModule,
} from '@nestjs/typeorm';
import { UserController } from './user.controller';
import { UserService } from './user.service';
import { User } from './user.entity';
import { DataSource } from 'typeorm';
import { customUserRepository } from './user.repository';
@Module({
imports: [TypeOrmModule.forFeature([User])],
controllers: [UserController],
providers: [
{
provide: getRepositoryToken(User),
inject: [getDataSourceToken()],
useFactory(datasource: DataSource) {
return datasource.getRepository(User).extend(customUserRepository);
},
},
UserService,
],
})
export class UserModule {}
In this example, we’ve imported the TypeOrmModule
and used the forFeature
method to register the User
entity with the module. This makes the repository for the User
entity available for injection into any services or controllers within the module.
We’ve also defined a provider that uses the getRepositoryToken
and getDataSourceToken
functions to inject the custom repository into the module. The **useFactory**
function returns an instance of the **Repository**
class for the **User**
entity, which we've extended with the **customUserRepository**
object. This allows us to use the custom repository methods in our module.
Conclusion
In this article, we’ve looked at how to create and use custom repositories in NestJS with TypeORM 0.3. We’ve defined a custom repository interface, implemented it with custom methods, injected it into a NestJS service, and registered it with a NestJS module.
Custom repositories are a useful way to add custom methods or queries to the Repository
class, which can help you reuse code and add additional functionality to your application. By following the steps in this article, you can easily create and use custom repositories in your NestJS applications with TypeORM 0.3.
It’s always appreciated when readers take the time to comment, follow, and share with their friends. If you found this article helpful, please consider supporting me by following me and subscribing to my YouTube channel.
Your support helps me to continue creating and sharing helpful content with the community. Thank you for your support!
Disclaimer*: The NestJS and TypeORM logos are trademarks of their respective brands. The use of these logos in this article is for informational purposes only and does not imply any endorsement or affiliation with the brands.*