In the world of modern web development, building scalable and efficient applications requires a solid foundation in managing databases. PostgreSQL is a powerful open-source relational database management system that is widely used for its performance and reliability. When combined with the TypeORM library in a NestJS application, it becomes a potent combination for managing database connections and interactions. This article will guide you through the process of establishing a PostgreSQL connection using TypeORM within a NestJS setup, including setting up a PostgreSQL database using Docker and creating a Poll API example.
Prerequisites
Before we dive into the details, make sure you have the following tools and technologies installed on your system:
Node.js and npm: To run the NestJS application.
Docker: For setting up a PostgreSQL database in a Docker container.
Nest CLI: To generate and manage your NestJS application.
Step 1: Create a NestJS Application
Let’s start by creating a new NestJS application. Open your terminal and execute the following command:
nest new poll-api
Navigate to the project directory:
cd poll-api
Step 2: Install TypeORM and PostgreSQL Package
TypeORM is a popular Object-Relational Mapping (ORM) library for TypeScript and JavaScript. It simplifies database operations by allowing developers to interact with databases using TypeScript classes and decorators.
Install TypeORM and the PostgreSQL driver as project dependencies:
npm install @nestjs/typeorm typeorm pg
Step 3: Set Up a PostgreSQL Database Using Docker
Docker is an essential tool for creating isolated development environments. We will use Docker to set up a PostgreSQL database server for our NestJS application.
Create a docker-compose.yml file in the root directory of your project:
version: '3.7'
services:
postgres:
image: postgres:13
container_name: postgres_db
ports:
- '5432:5432'
environment:
POSTGRES_DB: poll_db
POSTGRES_USER: poll_user
POSTGRES_PASSWORD: poll_password
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
This Docker Compose configuration sets up a PostgreSQL container named postgres_db with a database named poll_db, a user named poll_user, and the associated password.
Run the PostgreSQL container using Docker Compose:
docker compose up -d
Step 4: Configure TypeORM Connection
Open the src/app.module.ts file and configure the TypeORM connection. Import the necessary modules and configure the TypeOrmModule.forRoot() method with the PostgreSQL connection options:
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'postgres',
host: 'localhost',
port: 5432,
username: 'poll_user',
password: 'poll_password',
database: 'poll_db',
entities: [],
synchronize: true,
}),
],
})
export class AppModule {}
Step 5: Create a Poll Entity
Create a poll.entity.ts file in the src/poll directory. Define the Poll entity using TypeORM decorators:
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
@Entity()
export class Poll {
@PrimaryGeneratedColumn()
id: number;
@Column()
question: string;
@Column('jsonb', { nullable: true })
options: string[];
}
Step 6: Create a Poll Service
Create a poll.service.ts file in the src/poll directory. Implement the PollService class, which will be responsible for interacting with the database:
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Poll } from './poll.entity';
@Injectable()
export class PollService {
constructor(
@InjectRepository(Poll)
private readonly pollRepository: Repository<Poll>,
) {}
async createPoll(question: string, options: string[]): Promise<Poll> {
const poll = this.pollRepository.create({ question, options });
return this.pollRepository.save(poll);
}
async getAllPolls(): Promise<Poll[]> {
return this.pollRepository.find();
}
}
Step 7: Create a Poll Controller
Create a poll.controller.ts file in the src/poll directory. Implement the PollController class, which will handle incoming HTTP requests related to polls:
import { Controller, Get, Post, Body } from '@nestjs/common';
import { PollService } from './poll.service';
@Controller('polls')
export class PollController {
constructor(private readonly pollService: PollService) {}
@Post()
createPoll(@Body() { question, options }: { question: string; options: string[] }) {
return this.pollService.createPoll(question, options);
}
@Get()
getAllPolls() {
return this.pollService.getAllPolls();
}
}
Step 8: Configure Module
Open the src/app.module.ts file again and import the PollController and PollService.
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Poll } from './poll/poll.entity';
import { PollService } from './poll/poll.service';
import { PollController } from './poll/poll.controller';
@Module({
imports: [
TypeOrmModule.forRoot({
// ... (previous TypeORM config)
entities: [Poll],
synchronize: true,
}),
TypeOrmModule.forFeature([Poll]),
],
providers: [PollService],
controllers: [PollController],
})
export class AppModule {}
Step 9: Test the API
Start the NestJS application by running the following command:
npm run start:dev
You can now access the API endpoints using tools like curl or Postman:
Create a poll: POST http://localhost:3000/polls
Request Body:
{
"question": "What's your favorite programming language?",
"options": ["JavaScript", "Python", "Java", "C++"]
}
Get all polls: GET http://localhost:3000/polls
Conclusion
In this detailed guide, we have learned how to establish a PostgreSQL connection using TypeORM within a NestJS application. We set up a PostgreSQL database using Docker, defined a Poll entity, created a Poll service, and implemented API endpoints to create and retrieve polls. This foundation provides a strong basis for building more complex and feature-rich applications using the NestJS framework, PostgreSQL, and TypeORM.
Here’s a link to a sample project repository for a more concrete demonstration of the concepts discussed in this article: Github Repo
Top comments (2)
This article is misleading, please review carefully.
You need to setup everything on the docker-compose file not only the postgre. Also you are adding libraries which are not really needed.
Thank you
Nice post!
Later if you want to replace TypeORM generated-DB keys with your customized and readable ones, you may go through my recent post.
A journey to simplify debugging: Automate generating human-friendly database constraints using TypeORM
Emtiaj Hasan ・ Aug 6