How to use TypeOrmModule forFeature and forRoot Methods

Posted October 1, 2023
How to use TypeOrmModule forFeature and forRoot Methods

If you are working with TypeORM, you must use the forFeature and forRoot methods to configure your modules. This guide dives deeper into how to use forFeature and forRoot to get your TypeOrmModule right.

Before exploring how to use TypeOrmModule forFeature and forRoot Methods with PostgreSql, let’s learn what each represents and how it is used within Nest.js.

Step 1: Understanding TypeOrmModule forFeature

forFeature import and configure entities within the feature module. It must be used to only load entities available in the scope of a specific module.

Take an example of a Product module. In this case, TypeOrmModule will use forFeature to load entities related to the Product as follows:

// products.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UserController } from './product.controller';
import { ProductService } from './product.service';
import { Product } from './product.entity';

@Module({
  imports: [TypeOrmModule.forFeature([Product])],
  controllers: [ProductController],
  providers: [ProductService],
})
export class ProductModule {}

Note that [TypeOrmModule.forFeature([Product])] makes the Product Entity available in the scope of the ProductModule.

Related: How to use TypeOrmModule forRootAsync and configService

Related: How to use TypeOrmModuleOptions Within a NestJS App

Step 2: TypeOrmModule forRoot and How to Use It

Once you have forFeature ready, NestJS must be able to load TypeORM at the entry point using the main Module (app.module.ts). It’s here that TypeOrmModule will use forRoot.

This way, TypeORM will instruct NestJS to configure the TypeORM module at the root level so you can have your database ready before NestJS creates the application graph that extends to your feature modules.

You must understand that TypeOrmModule forRoot will configure the global TypeORM settings for accessing your database and the entities TypeORM will look for. Thus, forRoot will take the following shape:

// app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'username',
      password: 'password',
      database: 'database_name',
      entities: [__dirname + '/**/*.entity{.ts,.js}'],
      synchronize: true,
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

These settings are for MySQL. If, for example, you want to use PostgreSQL, you just need to ensure you have pg installed using NPM and type: 'mysql' to type: 'postgres'. Then, update other values with your actual database connection details.

Step 3: How to Implement TypeOrmModule forFeature Method

At this point, you need to have a ready NestJS app:

npm i -g @nestjs/cli
nest new typeorm-app

Change the directory to this new app, cd typeorm-app and install TypeORM and the database driver you want to use:

npm i typeorm @nestjs/typeorm pg

Then, create a feature module of your choice while adding provider and controller structure:

nest g module task
nest g service task --no-spec
nest g controller task --no-spec

You will need an entity file in the created src/task module. Name it the task.entity.ts file.

How to use TypeOrmModule forFeature and forRoot Methods

Here, you will define your database table entities using TypeORM as follows:

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

@Entity('task') // maps the Task entity to the task table in the database
export class Task {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ name: 'name', length: 70, nullable: false })
  name: string;

  @Column({ name: 'description', length: 180, nullable: false })
  description: string;
}

The first step is to ensure TypeOrmModule has access to this feature module and its related entities. This means you will use the forFeature method to load the Task Entity in your task.module.ts module file as follows:

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { TaskService } from './task.controller';
import { TaskService } from './task.service';
import { Task } from './entities/task.entity';

@Module({
  // import and use forFeature
  imports: [TypeOrmModule.forFeature([Task])],
  controllers: [TaskController],
  providers: [TaskService],
})
export class TaskModule {}

Step 4: Adding TypeOrmModule forRoot to NestJS with PostgreSql

Once forFeature is ready, TypeOrmModule can now use forRoot to configure the TypeORM module at the root level as follows in the app.module.ts file:

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { TaskModule } from './task/task.module';
// TypeOrmModule database integration
import { TypeOrmModule } from '@nestjs/typeorm'; 

@Module({
  imports: [TypeOrmModule.forRoot({
      // TypeORM PostgreSQL DB Drivers
      type: 'postgres',
      host: 'localhost',
      port: 5432,
      username: 'postgres',
      password: 'pass',
      //database name
      database: 'task',
      // Synchronize database schema with entities 
      entities: [__dirname + '/**/*.entity{.ts,.js}'],
      synchronize: false, // use false if you need migrations
  }),
  // Make sure the feature module is loaded
    TaskModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

At this point, run your app and watch TypeORM magic. TypeOrmCoreModule and TypeOrmModule dependencies will be initialized.

How to use TypeOrmModule forFeature and forRoot Methods

At the same time, NestJS should use TypeORM and map your entities to the database:

How to use TypeOrmModule forFeature and forRoot Methods

Conclusion

This is basic TypeOrmModule forFeature and forRoot setup. It shows you how to encapsulate your code while clearly separating concerns between global settings and feature-specific configurations. I hope you found it Helpful!

How to use TypeOrmModule forFeature and forRoot Methods

Written By:

Joseph Chege