NestJS is a progressive Node.js framework for building efficient and scalable server-side applications. In this guide, we’ll walk through setting up a NestJS project with PostgreSQL as the database and TypeORM as the ORM, and implement CRUD operations for a simple Tag entity.
blog-nest/
├── eslint.config.mjs
├── nest-cli.json
├── package.json
├── README.md
├── tsconfig.build.json
├── tsconfig.json
├── src/
│ ├── app.controller.spec.ts
│ ├── app.controller.ts
│ ├── app.module.ts
│ ├── app.service.ts
│ ├── main.ts
│ ├── ormconfig.ts
│ └── tag/
│ ├── tag.controller.ts
│ ├── tag.entity.ts
│ ├── tag.module.ts
│ └── tag.service.ts
└── test/
├── app.e2e-spec.ts
└── jest-e2e.json
1. Project Setup
Install NestJS CLI and Create a Project.
npm i -g @nestjs/cli
nest new blog-nest
Install Dependencies
npm install @nestjs/typeorm typeorm pg
@nestjs/typeorm: NestJS integration for TypeORMtypeorm: ORM for TypeScript and JavaScriptpg: PostgreSQL driver
2. Configure TypeORM and PostgreSQL
Create or update ormconfig.ts:
import { DataSource } from 'typeorm';
export default new DataSource({
type: 'postgres',
host: 'localhost',
port: 5432,
username: 'your_db_user',
password: 'your_db_password',
database: 'blog_nest',
entities: [__dirname + '/**/*.entity{.ts,.js}'],
synchronize: true, // Don't use in production
});
In app.module.ts, import TypeOrmModule:
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import ormconfig from './ormconfig';
@Module({
imports: [
TypeOrmModule.forRoot(ormconfig),
// ...other modules
],
})
export class AppModule {}
3. Create the Tag Entity
Create tag.entity.ts:
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
@Entity({ name: 'tags' })
export class TagEntity {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
}
4. Generate Tag Module, Service, and Controller
nest generate module tag
nest generate service tag
nest generate controller tag
5. Implement CRUD in Tag Service
tag.service.ts:
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { TagEntity } from './tag.entity';
@Injectable()
export class TagService {
constructor(
@InjectRepository(TagEntity)
private readonly tagRepository: Repository<TagEntity>,
) {}
async getAll(): Promise<TagEntity[]> {
return this.tagRepository.find();
}
async getById(id: number): Promise<TagEntity> {
return this.tagRepository.findOneBy({ id });
}
async create(name: string): Promise<TagEntity> {
const tag = this.tagRepository.create({ name });
return this.tagRepository.save(tag);
}
async update(id: number, name: string): Promise<TagEntity> {
await this.tagRepository.update(id, { name });
return this.getById(id);
}
async delete(id: number): Promise<void> {
await this.tagRepository.delete(id);
}
}
6. Implement Tag Controller
tag.controller.ts:
import { Controller, Get, Post, Put, Delete, Param, Body } from '@nestjs/common';
import { TagService } from './tag.service';
@Controller('tags')
export class TagController {
constructor(private readonly tagService: TagService) {}
@Get()
getAll() {
return this.tagService.getAll();
}
@Get(':id')
getById(@Param('id') id: number) {
return this.tagService.getById(id);
}
@Post()
create(@Body('name') name: string) {
return this.tagService.create(name);
}
@Put(':id')
update(@Param('id') id: number, @Body('name') name: string) {
return this.tagService.update(id, name);
}
@Delete(':id')
delete(@Param('id') id: number) {
return this.tagService.delete(id);
}
}
7. Run the Application
npm run start:dev
Your API will be available at http://localhost:3000/tags.
8. Testing the Endpoints
You can use tools like Postman or curl to test the CRUD endpoints:
GET /tags— List all tagsGET /tags/:id— Get a tag by IDPOST /tags— Create a new tag ({ "name": "nestjs" })PUT /tags/:id— Update a tagDELETE /tags/:id— Delete a tag