Tin tức và phân tích của tất cả các thiết bị di động

Cách xây dựng API CRUD REST của Nest.js bằng TypeORM và PostgreSQL

Giống như các khung Node.js khác, Nest.js cung cấp một bộ công cụ toàn diện để xây dựng các dịch vụ phụ trợ mạnh mẽ và có thể mở rộng. Tuy nhiên, điều quan trọng là phải hiểu cách triển khai hiệu quả các thao tác Tạo, Đọc, Cập nhật và Xóa (CRUD) trong Nest.js – đây là những thao tác cơ bản nhất trong quá trình phát triển API.

Tìm hiểu cách xây dựng API CRUD REST của Nest.js bằng TypeORM và cơ sở dữ liệu PostgreSQL.

Bắt đầu với Nest.js

Để bắt đầu, hãy cài đặt công cụ dòng lệnh Nest.js:

 npm i -g @nestjs/cli 

Sau đó tạo một dự án mới bằng cách chạy:

 nest new crud-app 

Công cụ CLI sẽ nhắc bạn chọn trình quản lý gói, chọn tùy chọn phù hợp nhất với bạn. Chúng tôi sẽ sử dụng npm, Node.

CLI sẽ xây dựng một dự án Nest.js cơ bản với tất cả các tệp cấu hình cần thiết và các phần phụ thuộc ban đầu cần có để chạy ứng dụng.

Cuối cùng, vào thư mục dự án và khởi động máy chủ phát triển.

 cd crud-app
npm run start

Bạn có thể tìm thấy mã cho dự án này trong kho GitHub của nó.

Tạo cơ sở dữ liệu PostgreSQL

Hướng dẫn này sử dụng phiên bản PostgreSQL trên đám mây nhưng thay vào đó, bạn có thể thiết lập cơ sở dữ liệu PostgreSQL cục bộ. Bạn có thể cài đặt PostgreSQL trên hệ thống của mình WindowsmacOS hoặc Linux.

Để thiết lập phiên bản PostgreSQL trên đám mây:

  • Hãy truy cập ElephantSQL để đăng ký và đăng nhập vào trang tổng quan về tài khoản của bạn.
  • Nhấp vào nút Tạo phiên bản mới ở trên cùng bên trái của trang để tạo phiên bản mới cho ứng dụng của bạn.
  • Nhập tên phiên bản của bạn, chọn gói miễn phí và cuối cùng chọn khu vực để hoàn tất quá trình cài đặt.
  • Khi phiên bản cơ sở dữ liệu được tạo, hãy chuyển đến trang cài đặt và sao chép URL cơ sở dữ liệu đã cho.
  • Cấu hình kết nối cơ sở dữ liệu

    Trong thư mục gốc của dự án, tạo tệp .env và dán URL kết nối cơ sở dữ liệu như sau:

     DATABASE_URL="<your connection url here>" 

    Bây giờ cài đặt các gói này:

     npm install pg typeorm @nestjs/typeorm @nestjs/config 

    Sau đó hãy tiếp tục và tạo một mô-đun cơ sở dữ liệu bằng công cụ CLI.

     nest g module database 

    Mở tệp cơ sở dữ liệu/database.module.ts và thêm mã cấu hình cơ sở dữ liệu sau:

     import { Module } from '@nestjs/common';
    import { ConfigModule, ConfigService } from '@nestjs/config';
    import { TypeOrmModule } from '@nestjs/typeorm';
    import { User } from '../users/models/user.entity';

    @Module({
      imports: [
        TypeOrmModule.forRootAsync({
          imports: [ConfigModule],
          inject: [ConfigService],

          useFactory: async (configService: ConfigService) => ({
            type: 'postgres',
            url: configService.get('DATABASE_URL'),
            entities: [User],
            synchronize: true
          }),
        }),
      ],
    })

    export class DatabaseModule {}

    Mô-đun cơ sở dữ liệu này xử lý kết nối bằng cách định cấu hình mô-đun TypeORM với tham số kết nối được yêu cầu, URL cơ sở dữ liệu.

    Ngoài ra, nó còn định nghĩa thực thể Người dùng như một phần của cấu hình xác định cấu trúc và thuộc tính của dữ liệu được lưu trữ trong bảng cơ sở dữ liệu PostgreSQL.

    Tại thời điểm này, mã của bạn có thể sẽ gặp lỗi vì bạn chưa tạo thực thể người dùng. Bạn sẽ làm điều đó trong các bước dưới đây.

    Cập nhật tệp app.module.ts

    Cuối cùng, cập nhật mô-đun ứng dụng chính để bao gồm cấu hình của mô-đun cơ sở dữ liệu.

     import { Module } from '@nestjs/common';
    import { ConfigModule } from '@nestjs/config';
    import { AppController } from './app.controller';
    import { AppService } from './app.service';
    import { DatabaseModule } from './database/database.module';

    @Module({
      imports: [
        ConfigModule.forRoot({
          envFilePath: '.env',
        }),
        DatabaseModule,
      ],

      controllers: [AppController],
      providers: [AppService],
    })

    export class AppModule {}

    Xác định mô-đun người dùng

    Mô-đun người dùng đóng vai trò là thành phần tập trung chịu trách nhiệm đóng gói và quản lý logic cần thiết để triển khai chức năng API CRUD.

    Chạy lệnh đầu cuối này để tạo mô-đun người dùng API.

     nest g module users 

    Công cụ CLI tự động cập nhật tệp app.module.ts để phản ánh những thay đổi đã thực hiện, ngoài việc tạo mô-đun tùy chỉnh. Điều này đảm bảo rằng mô-đun mới được tạo, tức là người dùng, sẽ được tích hợp đúng cách với cấu hình của mô-đun ứng dụng.

    Tạo một thực thể người dùng

    TypeORM là thư viện ánh xạ quan hệ đối tượng (ORM) giúp đơn giản hóa việc tương tác cơ sở dữ liệu trong các ứng dụng TypeScript bằng cách ánh xạ các đối tượng JavaScript vào các bảng cơ sở dữ liệu.

    Khi bạn tạo một thực thể người dùng bằng TypeORM, bạn xác định cấu trúc và thuộc tính của dữ liệu người dùng trong cơ sở dữ liệu PostgreSQL.

    Trong thư mục người dùng, tạo models/user.entity.ts mới và thêm mã sau đây.

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

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

        @Column()
        name: string;

        @Column()
        email: string;
    }

    Thực thể Người dùng xác định cấu trúc dữ liệu người dùng được lưu trữ trong cơ sở dữ liệu. Trong trường hợp này, ID là cột khóa chính, cột tên và địa chỉ email cũng như các thuộc tính tương ứng của chúng.

    Tạo dịch vụ API CRUD

    Bây giờ hãy tạo một dịch vụ API sẽ quản lý logic hoạt động CRUD bằng cách chạy lệnh bên dưới:

     nest g service users 

    Mở tệp user-auth.service.ts và thêm mã này:

     import { Injectable } from '@nestjs/common';
    import { InjectRepository } from '@nestjs/typeorm';
    import { Repository } from 'typeorm';
    import {User} from './models/user.entity';

    @Injectable()
    export class UsersService {
      constructor(
        @InjectRepository(User)
        private userRepository: Repository<User>,
      ) {}

      async findAll(): Promise<User[]> {
        return this.userRepository.find();
      }

      async findOne(id: number): Promise<User> {
        return this.userRepository.findOne({ where: { id } });
      }

      async create(user: Partial<User>): Promise<User> {
        const newuser = this.userRepository.create(user);
        return this.userRepository.save(newuser);
      }

      async update(id: number, user: Partial<User>): Promise<User> {
        await this.userRepository.update(id, user);
        return this.userRepository.findOne({ where: { id } });
      }

      async delete(id: number): Promise<void> {
        await this.userRepository.delete(id);
      }
    }

    Lớp UsersService này định nghĩa các phương thức API khác nhau dành riêng cho việc xử lý các hoạt động CRUD. Các phương pháp này bao gồm truy xuất dữ liệu của tất cả người dùng, tìm một người dùng cụ thể theo số ID của họ, tạo người dùng mới, cập nhật người dùng hiện có và phương pháp xóa dữ liệu của một người dùng cụ thể khỏi cơ sở dữ liệu.

    Xác định bộ điều khiển cho API

    Tạo bộ điều khiển sẽ quản lý điểm cuối API cho các hoạt động liên quan đến người dùng.

     nest g controller users 

    Sau đó thêm mã sau vào tệp user.controller.ts.

     import { Controller, Get, Post, Body, Put, Param, Delete, NotFoundException, HttpCode } from '@nestjs/common';
    import { UsersService } from './users.service';
    import { User } from './models/user.entity';

    @Controller('api/users')
    export class UsersController {
      constructor(private readonly usersService: UsersService) {}

      @Get()
      async findAll(): Promise<User[]> {
        return this.usersService.findAll();
      }

      @Post()
      @HttpCode(201)
      async create(@Body() user: User): Promise<User> {
        const createdUser = await this.usersService.create(user);
        return createdUser;
      }

      @Put(':id')
      async update (@Param('id') id: number, @Body() user: User): Promise<any> {
        await this.usersService.update(id, user);
        return { message: 'User updated successfully' };
      }

      @Delete(':id')
      async delete(@Param('id') id: number): Promise<any> {
        const user = await this.usersService.findOne(id);

        if (!user) {
          throw new NotFoundException('User does not exist!');
        }

        await this.usersService.delete(id);
        return { message: 'User deleted successfully' };
      }
    }

    Bộ điều khiển quản lý các điểm cuối API cho hoạt động của người dùng. Nó hỗ trợ các yêu cầu GET để khôi phục tất cả người dùng, yêu cầu POST để tạo người dùng mới, yêu cầu PUT để cập nhật người dùng hiện tại và yêu cầu DELETE để xóa người dùng.

    Bằng cách sử dụng UsersService và tương tác với thực thể Người dùng, bộ điều khiển này cung cấp API hoàn chỉnh để quản lý các hoạt động liên quan đến người dùng trên dữ liệu được lưu trữ trong cơ sở dữ liệu.

    Cập nhật tệp user.module.ts

    Cuối cùng, hãy cập nhật tệp user.module.ts như hiển thị bên dưới để đảm bảo bạn bao gồm thực thể Người dùng và mô-đun TypeORM thiết lập kết nối cơ sở dữ liệu.

     import { Module } from '@nestjs/common';
    import { UsersController } from './users.controller';
    import { UsersService } from './users.service';
    import { TypeOrmModule } from '@nestjs/typeorm';
    import { User } from './models/user.entity';

    @Module({
      imports: [TypeOrmModule.forFeature([User])],
      controllers: [UsersController],
      providers: [UsersService]
    })

    export class UsersModule {}

    Cuối cùng, hãy tiếp tục và khởi động máy chủ phát triển của bạn để kiểm tra các hoạt động CRUD với Postman.

     npm run start 

    Máy chủ sẽ khởi động trên cổng 3000 và bạn có thể thực hiện các yêu cầu API tới nó tại http://localhost:3000/api/users.

    Tạo ứng dụng phụ trợ với Nest.js

    Cho dù bạn đang xây dựng một API REST đơn giản hay một ứng dụng web phức tạp, Nest.js đều cung cấp một bộ tính năng và khả năng toàn diện để xây dựng một hệ thống phụ trợ mạnh mẽ và đáng tin cậy.

    Nest.js cung cấp cách tiếp cận có cấu trúc hơn để phát triển dự án so với Express.js. Điều này đảm bảo rằng bạn có thể tự tin xây dựng, mở rộng quy mô và duy trì các ứng dụng phức tạp với mẫu thiết kế theo mô-đun và có tổ chức.