TypeORM is a popular ORM that is written entirely in Typescript. It’s a robust library that offers the ability to use both the Active Record and Data Mapper patterns. It’s also a library that goes well with Nest.js, a Typescript framework that sits on top of Express.js. In this tutorial, we will talk about how to use the two technologies in conjunction to make a Rest API. If you’re interested in seeing the video tutorials, please click here. We also have an article on how to add authentication here.

DB Configuration

We must first start off by creating a new NestJS project. We can do this by running the following command.

nest new typeorm-example

We will then add the dependencies for TypeORM and PostgreSQL

npm install --save @nestjs/typeorm typeorm pg

You can then add the ormconfig.json file to set up your db connection

{
    "type": "postgres",
    "host": "localhost",
    "port": 5432,
    "username": "jamescoonce",
    "password": "",
    "database": "NestTypeORMTodo",
    "entities": [
        "src/**/**.entity{.ts,.js}"
    ],
    "synchronize": true
}

You will then add your TypeOrmModule to your AppModule file to register your DB config.

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

@Module({
  imports: [TypeOrmModule.forRoot()],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

You can also place to configuration directly in the forRoot() method

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

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'postgres',
      host: 'localhost',
      port: 5432,
      username: 'jamescoonce',
      password: '',
      database: 'NestTypeORMTodo',
      entities: [Todo],
      synchronize: true,
    }),
    TodosModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

Todo Domain Creation

We will first create the domain for our Todos.

nest generate module todos
nest generate controller todos
nest generate service todos

Now you can create a Response Object for the Todo.

export class TodoRO {
  id: number;
  text: string;
  complete: boolean;
}

Now you can create your todo.entity.ts file

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

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

  @Column()
  text: string;

  @Column()
  complete: boolean;
}

You can also add Swagger documentation and create a dto for your Todo.

npm install --save @nestjs/swagger swagger-ui-express
import { ApiProperty } from '@nestjs/swagger';

export class CreateTodoDto {
  @ApiProperty()
  readonly id: number;

  @ApiProperty()
  readonly text: string;

  @ApiProperty()
  readonly complete: boolean;
}

Now that we have our DTOs created, we can now create our service.

import { Injectable } from '@nestjs/common';
import { Todo } from './todo.entity';
import { Repository, DeleteResult } from 'typeorm';
import { InjectRepository } from '@nestjs/typeorm';
import { CreateTodoDto } from './todos.dto';

@Injectable()
export class TodosService {
  constructor(
    @InjectRepository(Todo)
    private readonly todoRepository: Repository<Todo>,
  ) {}

  public async findAll(): Promise<Todo[]> {
    return await this.todoRepository.find();
  }


  public async findById(id: number): Promise<Todo | null> {
    return await this.todoRepository.findOneOrFail(id);
  }

  public async create(todo: CreateTodoDto): Promise<Todo> {
    return await this.todoRepository.save(todo);
  }

  public async update(
    id: number,
    newValue: CreateTodoDto,
  ): Promise<Todo | null> {
    const todo = await this.todoRepository.findOneOrFail(id);
    if (!todo.id) {
      // tslint:disable-next-line:no-console
      console.error("Todo doesn't exist");
    }
    await this.todoRepository.update(id, newValue);
    return await this.todoRepository.findOne(id);
  }

  public async delete(id: number): Promise<DeleteResult> {
    return await this.todoRepository.delete(id);
  }
}

We must also add the Todo entity to our Module.

import { Module } from '@nestjs/common';
import { TodosController } from './todos.controller';
import { TodosService } from './todos.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Todo } from './todo.entity';

@Module({
  imports: [TypeOrmModule.forFeature([Todo])],
  controllers: [TodosController],
  providers: [TodosService]
})
export class TodosModule {}

Now we can run our application and make requests.

Nest TypeORM Post Request
Nest TypeORM Get Request
NestJS Swagger

Conclusion

Creating Basic NestJS Rest APIs with Swagger documentation is simple. You can even add authentication to it. Check out our authentication article here and our video tutorials here.

Codebrains Newsletter

Get weekly dev news and tutorials.

Powered by ConvertKit