Introduction
Connecting an application to a database is a critical task for most backend systems. In this tutorial, we’ll learn how to connect a NestJS application to a PostgreSQL database using the latest syntax of NestJS and TypeScript, ensuring your application can interact with stored data effectively.
To follow along with this tutorial, you should have Node.js, NestJS CLI, and PostgreSQL installed on your system. Additionally, a basic understanding of TypeScript and NestJS concepts is recommended.
Setting up a New NestJS Project
Begin by creating a new NestJS project if you haven’t already:
$ nest new project-name
Navigate into your project directory:
$ cd project-name
Installing Required Modules
Install the @nestjs/typeorm
module and pg
which is the PostgreSQL client for Node.js:
$ npm install @nestjs/typeorm typeorm pg
Database Configuration
Add the TypeORM configuration to your app.module.ts
:
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'postgres',
host: 'localhost',
port: 5432,
username: 'your_username',
password: 'your_password',
database: 'your_database',
entities: [],
synchronize: true,
}),
//...other modules
],
//...other decorators
})
export class AppModule {}
Replacing 'your_username'
, 'your_password'
, and 'your_database'
with your PostgreSQL credentials.
Creating a Database Entity
Define a new entity that correlates with your database table. Create a new file user.entity.ts
with the following content:
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column()
email: string;
}
Don’t forget to include them in the entities
array of your TypeORM configuration.
Creating a Module
Create a module that uses the repository pattern to interact with your PostgreSQL data:
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './user.entity';
import { UserService } from './user.service';
@Module({
imports: [TypeOrmModule.forFeature([User])],
providers: [UserService],
exports: [UserService],
})
export class UserModule {}
Creating a Service
Create a service user.service.ts
to handle business logic:
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './user.entity';
@Injectable()
export class UserService {
constructor(
@InjectRepository(User)
private userRepository: Repository<User>,
) {}
findAll(): Promise<User[]> {
return this.userRepository.find();
}
findOne(id: string): Promise<User> {
return this.userRepository.findOne(id);
}
// Other CRUD operations
}
Creating a Controller
A controller can manage incoming requests. Here is a simple example for user.controller.ts
:
import { Controller, Get, Param } from '@nestjs/common';
import { UserService } from './user.service';
import { User } from './user.entity';
@Controller('users')
export class UserController {
constructor(private readonly userService: UserService) {}
@Get()
findAll(): Promise<User[]> {
return this.userService.findAll();
}
@Get(':id')
findOne(@Param('id') id: string): Promise<User> {
return this.userService.findOne(id);
}
// Other endpoints
}
Environment Variables for Safety
It’s a best practice to use environment variables instead of hardcoding your database credentials.
import { ConfigModule } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
// Within your AppModule or a suitable module
// Load ConfigModule which assists with environment variables
ConfigModule.forRoot({ envFilePath: '.env' });
// Refactor your TypeOrmModule setup to use environment variables
TypeOrmModule.forRoot({
type: 'postgres',
host: process.env.DB_HOST,
port: parseInt(process.env.DB_PORT, 10),
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
// ...other properties
// entities and synchronize as previously stated
})
Advanced Usage
Advanced configurations can involve separate environments, migrations, listeners/subscribers, and much more. You might need to configure additional options as your application grows.
Conclusion
In this tutorial, we’ve established a connection from a NestJS application to a PostgreSQL database, we’ve created entities, modules, services, and controllers to structure access to and querying of the database. Make sure to secure your application by using environment variables for your database credentials and keep growing your application with advanced TypeORM and NestJS features.