Backend Development

Nest.js CRUD Operations with TypeORM: A Comprehensive Guide

This tutorial provides a comprehensive guide to performing CRUD (Create, Read, Update, Delete) operations in a Nest.js application using TypeORM, a popular object-relational mapping (ORM) tool.

Bhavik Charola
6 min read

Nest.js CRUD Operations with TypeORM: A Comprehensive Guide

Building robust and scalable web applications often necessitates interacting with databases to manage data persistently. Nest.js, a progressive Node.js framework, provides a powerful platform for building efficient and scalable server-side applications. Coupled with TypeORM, a popular Object-Relational Mapping (ORM) tool, handling database operations like CRUD (Create, Read, Update, Delete) becomes significantly more streamlined and intuitive.

This comprehensive guide will walk you through implementing CRUD operations in your Nest.js application using TypeORM. We'll cover everything from setting up your project to performing advanced queries, empowering you to build data-driven applications with ease.

Why Nest.js and TypeORM for CRUD Operations?

Before diving into the implementation, let's understand why this pairing is so effective for managing data in your application:

  • Nest.js: Inspired by Angular, Nest.js offers a modular architecture, dependency injection, and TypeScript support, promoting code reusability, maintainability, and scalability.
  • TypeORM: An ORM like TypeORM acts as a bridge between your application code and the database, abstracting away complex SQL queries and offering an object-oriented approach to data manipulation. This simplifies database interactions and improves developer productivity.

Together, they create a potent combination for building data-driven applications, facilitating a clear separation of concerns and promoting clean, maintainable code.

Setting Up Your Nest.js Project with TypeORM

1. Project Initialization:

Start by creating a new Nest.js project using the Nest CLI:

npx @nestjs/cli new my-nest-crud-app

Navigate to your newly created project directory:

cd my-nest-crud-app

2. Install Dependencies:

Install the required dependencies for TypeORM and a database driver (we'll be using PostgreSQL in this example):

npm install --save @nestjs/typeorm typeorm pg

3. Database Configuration:

Configure your database connection details in the ormconfig.json file (create one in the root directory if it doesn't exist):

{
  "type": "postgres",
  "host": "localhost",
  "port": 5432,
  "username": "your_username",
  "password": "your_password",
  "database": "your_database",
  "entities": ["dist/**/*.entity{.ts,.js}"],
  "synchronize": true
}

4. TypeORM Module Integration:

Import the TypeORM module into your Nest.js application (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(), // Imports the TypeORM module globally
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

Defining Your Entity

An entity represents a table in your database. Let's define a simple Item entity:

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

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

  @Column()
  name: string;

  @Column()
  description: string;

  @Column({ default: false })
  isCompleted: boolean;
}

Implementing the CRUD Operations

Now, let's create a service to handle our CRUD operations:

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

@Injectable()
export class ItemsService {
  constructor(
    @InjectRepository(Item)
    private readonly itemsRepository: Repository<Item>,
  ) {}

  // Create
  async createItem(item: Item): Promise<Item> {
    return await this.itemsRepository.save(item);
  }

  // Read
  async findAllItems(): Promise<Item[]> {
    return await this.itemsRepository.find();
  }

  async findOneItem(id: number): Promise<Item> {
    return await this.itemsRepository.findOne({ where: { id } });
  }

  // Update
  async updateItem(id: number, item: Item): Promise<Item> {
    await this.itemsRepository.update(id, item);
    return await this.itemsRepository.findOne({ where: { id } });
  }

  // Delete
  async deleteItem(id: number): Promise<void> {
    await this.itemsRepository.delete(id);
  }
}

Next, create a controller to handle incoming requests and utilize the service:

import { Controller, Get, Post, Put, Delete, Body, Param } from '@nestjs/common';
import { ItemsService } from './items.service';
import { Item } from './item.entity';

@Controller('items')
export class ItemsController {
  constructor(private readonly itemsService: ItemsService) {}

  @Post()
  async create(@Body() item: Item) {
    return this.itemsService.createItem(item);
  }

  @Get()
  async findAll(): Promise<Item[]> {
    return this.itemsService.findAllItems();
  }

  @Get(':id')
  async findOne(@Param('id') id: number): Promise<Item> {
    return this.itemsService.findOneItem(id);
  }

  @Put(':id')
  async update(@Param('id') id: number, @Body() item: Item): Promise<Item> {
    return this.itemsService.updateItem(id, item);
  }

  @Delete(':id')
  async remove(@Param('id') id: number): Promise<void> {
    return this.itemsService.deleteItem(id);
  }
}

Conclusion

You've successfully implemented CRUD operations in your Nest.js application using TypeORM! This foundation empowers you to build dynamic and data-driven web applications. You can further enhance your API with features like pagination, filtering, and sorting to handle larger datasets efficiently.

While this guide provides a solid foundation for building backend systems, platforms like Code99.io can significantly accelerate your development workflow. Code99.io specializes in automating code generation, especially for repetitive tasks like setting up CRUD operations. By leveraging such tools, you can focus on the more intricate aspects of your application, boosting productivity and reducing development time.