Building Web Services with NestJS, TypeORM, and PostgreSQL
Building Web Services with NestJS, TypeORM, and PostgreSQL

Building Web Services with NestJS, TypeORM, and PostgreSQL

The combination of NestJS, TypeORM, and PostgreSQL provides a scalable, and efficient stack for developing web services. This article gives a general outline of constructing a basic, yet operational web service using these tools. We will look into the fundamentals of each element, and their collaboration, and guide you through a straightforward example to kickstart your project.

Introduction to the Stack

NestJS

I personally love the NestJS architecture.

NestJS is a Node.js framework for building efficient and scalable server-side applications. It is built with and fully supports TypeScript and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Reactive Programming).

TypeORM

TypeORM is an ORM (Object-Relational Mapping) library that can run in Node.js and can be used with TypeScript and JavaScript (ES5+). It supports the Active Record and Data Mapper patterns, unlike all other JavaScript ORMs currently in existence, which means you can write high-quality, loosely coupled, scalable, maintainable applications most efficiently.

PostgreSQL

PostgreSQL is a powerful, open-source object-relational database system that uses and extends the SQL language combined with many features that safely store and scale the most complicated data workloads.

Setting Up the Project

First, ensure you have Node.js, npm (or Yarn), and PostgreSQL installed on your machine.

1. Create a new NestJS project:

npm i -g @nestjs/cli nest new project-name        

Navigate into your project directory before proceeding.

2. Install TypeORM and PostgreSQL:

npm install --save @nestjs/typeorm typeorm pg        

3. Database Connection

Edit or create an ormconfig.json file in the root of your project to configure TypeORM with PostgreSQL:

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

4. Integrate Config into Nestjs

To add the ormconfig.json into the main root module, which is mostly named as app.module.ts :

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { TasksModule } from './tasks/tasks.module';

@Module({
  imports: [
    TasksModule,
    TypeOrmModule.forRoot(), // This will automatically use ormconfig.json
  ],
})
export class AppModule {}        

Since you have an ormconfig.json file, TypeORM can automatically load the connection options from this file. However, to explicitly tell NestJS to use it, you can import the configuration and pass it to the forRoot() method.

Building a Simple Web Service

Let’s create a simple CRUD (Create, Read, Update, Delete) application that manages a list of tasks.

Define the Task Entity

First, define a Task entity that TypeORM will use to create the tasks table in your PostgreSQL database.

Create a Task Entity

Inside the src folder, create a new folder named tasks. Inside tasks, create a file named task.entity.ts:

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

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

  @Column()
  title: string;

  @Column()
  description: string;
}        

Create a Task Module

NestJS is modular, so you’ll organize your code into modules. For the tasks, you’ll create a task module, service, and controller.

Generate Task Module, Service, and Controller: Run the following commands in your terminal:

nest generate module tasks
nest generate service tasks
nest generate controller tasks        

This will scaffold the necessary files and update the module imports automatically.

Implementing CRUD Operations

1. Update the Task Service:

Open the tasks.service.ts file and import the InjectRepository decorator from @nestjs/typeorm and the Repository from typeorm. Also, import the Task the entity you just created. Then, implement the CRUD operations:

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

@Injectable()
export class TasksService {
  constructor(
    @InjectRepository(Task)
    private tasksRepository: Repository<Task>,
  ) {}
  async findAll(): Promise<Task[]> {
    return this.tasksRepository.find();
  }
  async findOne(id: string): Promise<Task> {
    return this.tasksRepository.findOne(id);
  }
  async create(task: Task): Promise<Task> {
    return this.tasksRepository.save(task);
  }
  async update(id: string, task: Partial<Task>): Promise<Task> {
    await this.tasksRepository.update(id, task);
    return this.tasksRepository.findOne(id);
  }
  async remove(id: string): Promise<void> {
    await this.tasksRepository.delete(id);
  }
}        

2. Update the Task Controller:

In the tasks.controller.ts file, inject the TasksService and create endpoints to perform CRUD operations:

import { Controller, Get, Post, Put, Delete, Body, Param } from '@nestjs/common';
import { TasksService } from './tasks.service';
import { Task } from './task.entity';

@Controller('tasks')
export class TasksController {
  constructor(private tasksService: TasksService) {}

  @Get()
  getAll(): Promise<Task[]> {
    return this.tasksService.findAll();
  }

  @Get(':id')
  getOne(@Param('id') id: string): Promise<Task> {
    return this.tasksService.findOne(id);
  }

  @Post()
  create(@Body() task: Task): Promise<Task> {
    return this.tasksService.create(task);
  }

  @Put(':id')
  update(@Param('id') id: string, @Body() task: Task): Promise<Task> {
    return this.tasksService.update(id, task);
  }

  @Delete(':id')
  remove(@Param('id') id: string): Promise<void> {
    return this.tasksService.remove(id);
  }
}        

Ensure your TasksModule imports the TypeOrmModule.forFeature([Task]) to register the Task entity with our module:

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { TasksService } from './tasks.service';
import { TasksController } from './tasks.controller';
import { Task } from './task.entity';

@Module({
  imports: [TypeOrmModule.forFeature([Task])],
  providers: [TasksService],
  controllers: [TasksController],
})
export class TasksModule {}        

Running the Application

Before running the application, ensure your PostgreSQL database is running and accessible with the credentials you specified in ormconfig.json.

  1. Start the Application: use this command to run the server.

npm run start        

2. Testing Endpoints: Use a tool like Postman or cURL to test your endpoints. You should be able to create, retrieve, update, and delete tasks through your API.

Congratulations ??, you have done it!??

Conclusion

You’ve just built a simple web service using NestJS, TypeORM, and PostgreSQL. The combination of NestJS’s architecture, TypeORM’s ORM capabilities, and PostgreSQL’s reliability makes for a powerful trio in web development. As you become more familiar with these tools, you’ll be able to build more complex and feature-rich applications.

If you found this article helpful, don't forget to give it a clap ?? and share it with your colleagues!

Happy Coding ????????


Victor Chidi

Software Engineer

4 个月

Thanks for sharing, Asim Hafeez What about the migrations?

回复

要查看或添加评论,请登录

社区洞察

其他会员也浏览了