30 January, 2018

Add TypeORM to NestJS Project

This is the second part of Getting Started with NestJS. This document was updated to use NestJS 5.3.6

We add sqlite3 database support with TypeORM. Install TypeORM and sqlite3 for our project:

npm i -s @nestjs/typeorm typeorm sqlite3

In folder nestjs-backend/src create folder product.

In folder nestjs-backend/src/product create the file product.entity.ts.

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

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

  @Column({ length: 500 })
  name: string;

  @Column('text')
  description: string;
}

In folder nestjs-backend/src/product create the file product.service.ts.

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Product } from './product.entity';

@Injectable()
export class ProductService {
  constructor(
    @InjectRepository(Product)
    private readonly productRepository: Repository) {}

  async findAll(): Promise<Product[]> {
    return await this.productRepository.find();
  }

  async findByName(name: string): Promise {
    const result = await this.productRepository.find({ name: name });
    return result[0];
  }
}

In folder nestjs-backend/src/product create the file products.controller.ts

import { Get, Controller, Param } from '@nestjs/common';
import { ProductService } from './product.service';
import { Product } from './product.entity';

@Controller('products')
export class ProductsController {
    constructor(private readonly productService: ProductService) {}

    @Get()
    getProducts(): Promise<Product[]> {
      return this.productService.findAll();
    }

    @Get(':name')
    getProductByName(@Param() params: any): Promise {
      return this.productService.findByName(params.name);
    }
}

In folder nestjs-backend/src/product create the file product.module.ts

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

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

Update app.module.ts to use TypeOrmModule and ProductModule.

Configure TypeOrmModule to use sqlite.

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ProductModule } from './product/product.module';

@Module({
  imports: [TypeOrmModule.forRoot({
      type: 'sqlite',
      database: 'database.db',
      synchronize: true,
      logging: false,
      entities: [__dirname + '/../**/*.entity{.ts,.js}'],
    }),
    ProductModule],
  controllers: [AppController],
  providers: [],
})
export class ApplicationModule {}

Now start our server with npm start and access it through http://localhost:3000/products

It should return an empty array [].

To quickly test if we get anything persisted, change the constructor of ProductService in file product.service.ts to insert a new entity.

constructor(
    @InjectRepository(Product)
    private readonly productRepository: Repository) {
      const pr1 = new Product();
      pr1.description = 'First Product';
      pr1.name = 'product1';
      this.productRepository.save(pr1);
    }

Now restart and check by opening http://localhost:3000/products

Next we cant test our ProductsController.getProductByName with http://localhost:3000/products/product1

I have put the source code at GitHub https://github.com/ptea/nestjs-backend

To continue the next part: Authentication with Passport JWT