5-building-real-time-applications-with-nestjs-and-postgresql.html

Building Real-Time Applications with NestJS and PostgreSQL

In the era of instantaneous communication and data access, real-time applications have become a cornerstone of modern development. Whether it’s chat applications, live notifications, or collaborative tools, real-time functionality enhances user experience significantly. NestJS, a progressive Node.js framework, combined with PostgreSQL, a powerful relational database, offers a robust solution for building such applications. In this article, we’ll explore how to create real-time applications using NestJS and PostgreSQL, complete with detailed code examples and step-by-step instructions.

What is NestJS?

NestJS is a framework for building efficient, reliable, and scalable server-side applications. It leverages TypeScript and incorporates elements from both OOP (Object-Oriented Programming) and FP (Functional Programming). NestJS is modular in architecture, which allows developers to build complex applications by breaking them down into manageable modules.

Key Features of NestJS:

  • TypeScript Support: Provides type safety and modern JavaScript features.
  • Modular Architecture: Allows for code organization and reuse.
  • Built-in Support for WebSockets: Facilitates real-time communication.
  • Extensible: Can integrate with various libraries and frameworks.

What is PostgreSQL?

PostgreSQL is an advanced, open-source relational database management system known for its robustness and scalability. It supports a wide range of data types and has rich features including ACID compliance, full-text search, and JSON support.

Why Use PostgreSQL?

  • Reliability: Known for its data integrity and reliability.
  • Performance: Optimized for read and write speeds.
  • Extensibility: Supports custom data types and functions.

Use Cases for Real-Time Applications

Real-time applications can be used in various scenarios, including but not limited to:

  • Chat Applications: Instant messaging platforms.
  • Live Data Feeds: Stock market updates or sports scores.
  • Collaborative Tools: Real-time editing in document or project management applications.
  • Notifications: Alerting users about events or updates immediately.

Setting Up Your Environment

Before diving into coding, ensure your development environment is ready:

  1. Install Node.js: Download and install Node.js.
  2. Install PostgreSQL: Download and install PostgreSQL.
  3. Create a NestJS Project: bash npm i -g @nestjs/cli nest new real-time-app cd real-time-app

  4. Install Required Packages: bash npm install @nestjs/typeorm typeorm pg @nestjs/websockets @nestjs/platform-socket.io socket.io

Building the Real-Time Application

Step 1: Configure PostgreSQL Connection

Create a new file named ormconfig.json in the root directory of your project to configure the PostgreSQL connection:

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

Step 2: Create a Chat Module

Generate a chat module using the Nest CLI:

nest generate module chat
nest generate service chat
nest generate controller chat

Step 3: Define the Chat Entity

Create a new file chat.entity.ts inside the chat directory:

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

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

  @Column()
  username: string;

  @Column()
  message: string;

  @Column({ default: () => 'CURRENT_TIMESTAMP' })
  createdAt: Date;
}

Step 4: Implement WebSocket Gateway

In your chat.gateway.ts, set up the WebSocket gateway:

import {
  WebSocketGateway,
  WebSocketServer,
  SubscribeMessage,
  OnGatewayInit,
  Socket,
} from '@nestjs/websockets';
import { ChatService } from './chat.service';
import { Server } from 'socket.io';

@WebSocketGateway()
export class ChatGateway implements OnGatewayInit {
  @WebSocketServer() server: Server;

  constructor(private chatService: ChatService) {}

  afterInit(server: Server) {
    console.log('WebSocket server initialized');
  }

  @SubscribeMessage('sendMessage')
  async handleMessage(client: Socket, payload: { username: string; message: string }) {
    const chat = await this.chatService.createChat(payload);
    this.server.emit('newMessage', chat);
  }
}

Step 5: Implement Chat Service

In your chat.service.ts, implement the logic to save messages:

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

@Injectable()
export class ChatService {
  constructor(
    @InjectRepository(Chat)
    private chatRepository: Repository<Chat>,
  ) {}

  async createChat(chatData: { username: string; message: string }): Promise<Chat> {
    const chat = this.chatRepository.create(chatData);
    return this.chatRepository.save(chat);
  }
}

Step 6: Integrate Everything

Make sure to import the TypeOrmModule and your chat module in the main application module app.module.ts:

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ChatModule } from './chat/chat.module';

@Module({
  imports: [
    TypeOrmModule.forRoot(),
    ChatModule,
  ],
})
export class AppModule {}

Step 7: Run Your Application

Finally, run your application:

npm run start:dev

You can now access your real-time chat application by connecting a client through a WebSocket connection.

Conclusion

Building real-time applications with NestJS and PostgreSQL is a powerful way to leverage modern web technologies for dynamic user experiences. With the flexibility of NestJS and the robustness of PostgreSQL, developers can create scalable applications that respond to user actions in real-time. Whether you’re building a chat app or a collaborative tool, this stack can help you achieve your goals efficiently.

Actionable Insights

  • Optimize Database Queries: Use indexing in PostgreSQL to speed up data retrieval.
  • Error Handling: Implement robust error handling in your WebSocket connections to enhance user experience.
  • Testing: Regularly test your application to ensure real-time functionalities are working as expected.

By following these steps, you can create a fully functional real-time application that meets the needs of your users while leveraging the best practices in modern web development. Happy coding!

SR
Syed
Rizwan

About the Author

Syed Rizwan is a Machine Learning Engineer with 5 years of experience in AI, IoT, and Industrial Automation.