An Object-Relational Mapper (ORM) is a library that implements the Object-Relational mapping technique. This lets you write SQL database queries using the object-oriented paradigm of your preferred language.

TypeORM is a TypeScript ORM that makes interfacing with various databases very easy. It works with SQL databases but also interfaces nicely with NoSQL databases like MongoDB.

NestJS provides high-level support for TypeORM out-of-the-box. The dedicated TypeORM package makes integration relatively easy.

Step 1: Installing Dependencies

Before using TypeORM in a NestJS application, you must install it with its native NestJS package and your preferred SQL database. SQLite is a simple, install-free option.

Run the following command to install TypeORM and its native NestJS package, using the npm package manager:

        npm install @nestjs/typeorm typeorm

Run the following command to install SQLite:

        npm install sqlite3

Step 2: Creating an Entity

An entity is a collection of fields defining the data stored in a database. TypeORM uses the entity file to create a table in your database.

Follow the steps below to create an entity:

  1. Create a file in your application module and name it following the NestJS naming convention (<name>.entity.ts).
  2. In your entity file, import the Entity, Column, and PrimaryGeneratedColumn decorators from typeorm.
  3. In your entity file, create and export a class.
  4. Populate the class with the values you'd want in your database, like id, name, etc.
  5. Annotate your entity class with the Entity decorator. This makes your class recognizable to TypeORM as an entity.
  6. Annotate your id property with the PrimaryGeneratedColumn decorator. This tells TypeORM to mark the id as a primary key and auto-increment it.
  7. Annotate the remaining properties with the Column decorator. This adds them as columns in your database.

For example:

        // src/test/test.entity.ts
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';
 
@Entity()
export class Test {
  @PrimaryGeneratedColumn()
  id: number;
 
  @Column()
  property_1: string;
 
  @Column()
  property_2: string;
 
  @Column()
  property_3: string;
}

The entity file above creates this table in your database:

test

id

int(11)

PRIMARY KEY AUTO_INCREMENT

property_1

varchar(255)

property_2

varchar(255)

property_3

varchar(255)

The TypeORM documentation covers entities in further detail.

Step 3: Connecting Your Application to a Database

Now that your entity is set up, you'll need to connect your application to a database. This example uses SQLite.

Follow the steps below to connect your application to a database:

  1. In your applications root module (Usually the app.module.ts file), import TypeOrmModule from @nestjs/typeorm.
  2. In the same file, import all your entities.
  3. In the imports array, call the forRoot method on TypeOrmModule. The forRoot method shares the database connection through all the modules in your application.
  4. Pass an empty object as an argument into the forRoot method; this will be the TypeORM configuration object.
  5. Add a property, type, to the configuration object and set it to “sqlite”. The type property denotes the name of the database you’re using.
  6. Add another property, database, to the configuration object and set it to “test.db”. The database property denotes your preferred name for your database.
  7. Add another property, entities, to the configuration object and set it to an empty array. Populate the empty array with the entities you imported earlier.
  8. Add another property, synchronize, and set it true; this property syncs your entities to your database and updates it each time you run the code. You should only set this property to true in development. During production, you should set it to false to avoid data loss.
        // src/app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Test } from './test/test.entity';
import { Entity2 } from './entity/entity.entity';
import { TestModule } from './test/test.module';
 
@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'sqlite',
      database: 'test.db',
      entities: [Test, Entity2],
      synchronize: true, //development only
    }),
    TestModule,
  ],
  controllers: [],
  providers: [],
})

export class AppModule {}

Step 4: Creating a Repository

A repository is an entity’s access layer used to make queries (insert, delete, save, find, etc.) on a table created by the entity in the database. TypeORM supports the repository design pattern, thus, each entity has its own repository.

TypeORM automatically creates a repository for your entity when you follow the steps below:

  1. In your entity's module file, import TypeOrmModule from @nestjs/typeorm and import your entity.
  2. Create an imports array in the @Module decorator.
  3. In the imports array, call the forFeature method on TypeOrmModule.
  4. Pass an array as an argument into your and populate the array with your entity.
        // src/test/test.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { TestController } from './test.controller';
import { TestService } from './test.service';
import { Test } from './test.entity';
 
@Module({
  imports: [TypeOrmModule.forFeature([Test])],
  providers: [TestService],
  controllers: [TestController],
})

Step 5: Injecting Your Repository to Its Service Using Dependency Injection

Dependency injection is a software engineering technique that is a form of the inversion of control principle. It shifts the burden of dependency management from client code to the library or service it depends upon.

Follow the steps below to inject your repository into a service:

  1. In your service file, import Repository from typeorm and the InjectRepository decorator from @nestjs/typeorm. Also import the entity you want to inject its repository.
  2. In your service class, create a constructor.
  3. Declare a private variable, repo, as a parameter in the constructor to initialize it.
  4. Assign a type of Repository to repo with a generic type of your entity.
  5. Annotate repo with the InjectRepository decorator and pass your entity as an argument.
        // test.service.ts

import { Injectable } from '@nestjs/common';
import { Repository } from 'typeorm';
import { InjectRepository } from '@nestjs/typeorm';
import { Test } from './test.entity';
 
@Injectable()
export class TestService {
  constructor(
    @InjectRepository(Test)
    private repo: Repository<Test>,
  ) {}
}

Now that your setup is complete, you can make SQL queries on it to retrieve or modify data.

Making SQL Queries with TypeORM

You can make any simple SQL query by calling TypeORM’s repository methods on the repo variable inside your service class. You can also create complex SQL queries by using TypeORM’s query builder.