2k1
  • Home
  • Programming
  • System
  • Design
  • Applications
  • Tech
No Result
View All Result
  • Login
2k1
  • Home
  • Programming
  • System
  • Design
  • Applications
  • Tech
No Result
View All Result
2k1
No Result
View All Result

Khám Phá Các Thành Phần Cơ Bản Kiến Tạo Nên Ứng Dụng NestJS Mạnh Mẽ

Nguyen Pham by Nguyen Pham
02/09/2025
in Blog
Reading Time: 14 mins read
A A
0

Chào mừng các bạn đến với thế giới của NestJS – một framework Node.js tiến bộ, linh hoạt và cực kỳ mạnh mẽ, được xây dựng trên TypeScript và lấy cảm hứng từ Angular. Nếu bạn đang tìm kiếm một giải pháp để xây dựng các ứng dụng phía máy chủ hiệu quả, có khả năng mở rộng và dễ bảo trì, NestJS chính là lựa chọn không thể bỏ qua.

NestJS không chỉ cung cấp một cấu trúc rõ ràng mà còn áp dụng các nguyên tắc thiết kế phần mềm tốt nhất như Dependency Injection, OOP, và Functional Programming. Nhưng điều gì đã tạo nên sức mạnh và sự ổn định của NestJS? Đó chính là các thành phần cơ bản của nó. Trong bài viết này, chúng ta sẽ cùng nhau đi sâu vào từng “viên gạch” cấu thành nên một ứng dụng NestJS hoàn chỉnh.

NestJS Là Gì? Vì Sao Nên Chọn NestJS?

NestJS là một framework Node.js để xây dựng các ứng dụng phía máy chủ hiệu quả và có khả năng mở rộng. Nó sử dụng TypeScript làm ngôn ngữ chính, mang lại các lợi ích như kiểm tra kiểu tĩnh, IntelliSense tốt hơn và mã nguồn dễ đọc hơn. NestJS được thiết kế để giúp các nhà phát triển xây dựng các ứng dụng cấp doanh nghiệp, từ API RESTful đến các ứng dụng GraphQL, microservices và WebSockets.

Ưu điểm nổi bật:

  • Kiến trúc module hóa: Giúp tổ chức mã nguồn rõ ràng, dễ bảo trì.
  • Sử dụng TypeScript: Nâng cao chất lượng mã và năng suất phát triển.
  • Dependency Injection (DI): Giảm sự phụ thuộc giữa các thành phần, tăng tính kiểm thử và tái sử dụng.
  • Tương thích với Express/Fastify: Có thể tận dụng hệ sinh thái phong phú của Node.js.
  • Tài liệu phong phú và cộng đồng lớn: Dễ dàng tìm kiếm hỗ trợ và học hỏi.

Các Thành Phần Cơ Bản Trong NestJS

Để hiểu rõ cách NestJS hoạt động, chúng ta cần nắm vững các thành phần cốt lõi sau:

1. Modules (Mô-đun)

Mô-đun là khối xây dựng cơ bản của một ứng dụng NestJS. Mỗi ứng dụng NestJS có ít nhất một mô-đun gốc (root module), thường là AppModule. Các mô-đun được sử dụng để tổ chức mã nguồn thành các đơn vị chức năng gắn kết, giúp quản lý sự phức tạp của ứng dụng.

  • Đặc điểm:

    • Được định nghĩa bằng decorator @Module().
    • Tập hợp các controllers, providers và imports (các mô-đun khác).
    • exports: Các provider được cung cấp bởi mô-đun này và có thể được sử dụng bởi các mô-đun khác nhập nó.

  • Cấu trúc @Module():


    import { Module } from '@nestjs/common';
    import { AppController } from './app.controller';
    import { AppService } from './app.service';
    import { UsersModule } from './users/users.module'; // Import module khác

    @Module({
    imports: [UsersModule], // Nhập các mô-đun khác
    controllers: [AppController], // Danh sách các controller của mô-đun
    providers: [AppService], // Danh sách các provider (services, repositories, v.v.)
    exports: [], // Các provider được xuất để mô-đun khác sử dụng
    })
    export class AppModule {}

2. Controllers (Bộ điều khiển)

Controllers chịu trách nhiệm xử lý các yêu cầu đến và trả về phản hồi cho client. Chúng định nghĩa các endpoint (điểm cuối) cho API của bạn.

  • Đặc điểm:

    • Được định nghĩa bằng decorator @Controller().
    • Sử dụng các decorator HTTP method (@Get(), @Post(), @Put(), @Delete(), @Patch()) để định tuyến các yêu cầu đến các phương thức xử lý cụ thể.
    • Có thể sử dụng các decorator tham số như @Param(), @Query(), @Body() để truy cập dữ liệu từ yêu cầu.

  • Ví dụ:


    import { Controller, Get, Post, Body, Param } from '@nestjs/common';
    import { AppService } from './app.service';
    import { CreateUserDto } from './dto/create-user.dto';

    @Controller('users') // Định nghĩa tiền tố đường dẫn cho tất cả các route trong controller này
    export class UsersController {
    constructor(private readonly appService: AppService) {} // Tiêm AppService

    @Get()
    findAll(): string {
    return this.appService.getHello();
    }

    @Get(':id')
    findOne(@Param('id') id: string): string {
    return `This action returns a user #${id}`;
    }

    @Post()
    create(@Body() createUserDto: CreateUserDto): string {
    return `This action adds a new user: ${createUserDto.name}`;
    }
    }

3. Providers (Nhà cung cấp)

Providers là một khái niệm rộng trong NestJS, bao gồm các service, repository, factory, helper, v.v. Bất kỳ lớp nào được đánh dấu bằng @Injectable() đều có thể là một provider. Chúng là xương sống của kiến trúc NestJS, chứa logic nghiệp vụ và tương tác với các nguồn dữ liệu.

  • Đặc điểm:

    • Được định nghĩa bằng decorator @Injectable().
    • Có thể được “tiêm” (injected) vào các thành phần khác (như controllers hoặc các providers khác) thông qua Dependency Injection.
    • Chứa logic nghiệp vụ, xử lý dữ liệu, tương tác với cơ sở dữ liệu.

  • Ví dụ (Service là một loại provider phổ biến):


    import { Injectable } from '@nestjs/common';

    @Injectable()
    export class UsersService {
    private readonly users: any[] = []; // Ví dụ một mảng để lưu trữ người dùng

    create(user: any): void {
    this.users.push(user);
    }

    findAll(): any[] {
    return this.users;
    }

    findOne(id: string): any {
    return this.users.find(user => user.id === id);
    }
    }

4. Pipes (Bộ lọc dữ liệu)

Pipes là các lớp được sử dụng để chuyển đổi dữ liệu đầu vào hoặc xác thực dữ liệu. Chúng được thực thi trước khi một phương thức route handler được gọi.

  • Đặc điểm:

    • Thực hiện chuyển đổi dữ liệu (ví dụ: chuỗi sang số nguyên).
    • Thực hiện xác thực dữ liệu (ví dụ: kiểm tra tính hợp lệ của input).
    • Được định nghĩa bằng decorator @Injectable() và triển khai giao diện PipeTransform.
    • Có thể áp dụng ở cấp độ toàn cục, cấp độ controller, cấp độ phương thức hoặc cấp độ tham số.

  • Ví dụ (Sử dụng ParseIntPipe có sẵn):


    import { Controller, Get, Param, ParseIntPipe } from '@nestjs/common';
    import { UsersService } from './users.service';

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

    @Get(':id')
    findOne(@Param('id', ParseIntPipe) id: number): any { // id sẽ được chuyển đổi thành số nguyên
    return this.usersService.findOne(id.toString());
    }
    }

5. Guards (Bộ bảo vệ)

Guards là các lớp được sử dụng để kiểm soát quyền truy cập (authorization). Chúng quyết định xem một yêu cầu có được phép tiếp tục đến route handler hay không.

  • Đặc điểm:

    • Thực hiện logic xác thực quyền (ví dụ: kiểm tra vai trò người dùng, token JWT).
    • Được định nghĩa bằng decorator @Injectable() và triển khai giao diện CanActivate.
    • Chạy sau middleware và pipe, nhưng trước khi bất kỳ interceptor nào hoặc route handler được gọi.
    • Sử dụng decorator @UseGuards() để áp dụng.

  • Ví dụ (Một Guard đơn giản):


    import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
    import { Observable } from 'rxjs';

    @Injectable()
    export class AuthGuard implements CanActivate {
    canActivate(
    context: ExecutionContext,
    ): boolean | Promise<boolean> | Observable<boolean> {
    const request = context.switchToHttp().getRequest();
    // Giả sử có một logic kiểm tra token hoặc session
    return request.headers.authorization === 'Bearer my-secret-token';
    }
    }

    Để sử dụng:


    import { Controller, Get, UseGuards } from '@nestjs/common';
    import { AuthGuard } from './auth.guard';

    @Controller('admin')
    @UseGuards(AuthGuard) // Áp dụng AuthGuard cho tất cả các route trong controller này
    export class AdminController {
    @Get()
    getAdminData(): string {
    return 'This is admin data!';
    }
    }

6. Interceptors (Bộ chặn)

Interceptors cho phép bạn “chặn” và/hoặc sửa đổi các yêu cầu và phản hồi. Chúng có thể được sử dụng cho nhiều mục đích khác nhau như logging, chuyển đổi phản hồi, caching, hoặc xử lý lỗi.

  • Đặc điểm:

    • Được định nghĩa bằng decorator @Injectable() và triển khai giao diện NestInterceptor.
    • Có quyền truy cập vào ngữ cảnh thực thi (execution context) và luồng phản hồi (response stream).
    • Sử dụng decorator @UseInterceptors() để áp dụng.
  • Các trường hợp sử dụng phổ biến:

    • Chuyển đổi phản hồi thành một định dạng chuẩn.
    • Ghi log các tương tác người dùng hoặc lỗi.
    • Thêm tiêu đề vào phản hồi.
    • Xử lý caching.

  • Ví dụ (Interceptor để ghi log thời gian phản hồi):


    import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
    import { Observable } from 'rxjs';
    import { tap } from 'rxjs/operators';

    @Injectable()
    export class LoggingInterceptor implements NestInterceptor {
    intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const now = Date.now();
    return next
    .handle()
    .pipe(
    tap(() => console.log(`Request to ${context.getHandler().name} took ${Date.now() - now}ms`)),
    );
    }
    }

    Để sử dụng:


    import { Controller, Get, UseInterceptors } from '@nestjs/common';
    import { LoggingInterceptor } from './logging.interceptor';

    @Controller('items')
    @UseInterceptors(LoggingInterceptor)
    export class ItemsController {
    @Get()
    findAll(): string {
    return 'List of items';
    }
    }

7. Exception Filters (Bộ lọc ngoại lệ)

Exception Filters là các lớp được sử dụng để xử lý các ngoại lệ (exception) chưa được xử lý trong ứng dụng. Chúng cho phép bạn tùy chỉnh cách các lỗi được trình bày cho client.

  • Đặc điểm:

    • Được định nghĩa bằng decorator @Catch() và triển khai giao diện ExceptionFilter.
    • Cho phép bạn bắt và xử lý các loại ngoại lệ cụ thể (ví dụ: HttpException, Error).
    • Sử dụng decorator @UseFilters() để áp dụng.

  • Ví dụ (Filter tùy chỉnh cho HttpException):


    import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';
    import { Request, Response } from 'express';

    @Catch(HttpException)
    export class HttpExceptionFilter implements ExceptionFilter {
    catch(exception: HttpException, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const request = ctx.getRequest<Request>();
    const status = exception.getStatus();

    response
    .status(status)
    .json({
    statusCode: status,
    timestamp: new Date().toISOString(),
    path: request.url,
    message: exception.message,
    });


    }
    }



    Để sử dụng:


    import { Controller, Get, HttpException, HttpStatus, UseFilters } from '@nestjs/common';
    import { HttpExceptionFilter } from './http-exception.filter';

    @Controller('errors')
    export class ErrorsController {
    @Get('forbidden')
    @UseFilters(new HttpExceptionFilter()) // Áp dụng filter cho phương thức này
    getForbidden(): string {
    throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
    }
    }

Luồng Xử Lý Yêu Cầu Trong NestJS

Để hình dung rõ hơn, hãy xem xét luồng xử lý một yêu cầu HTTP đi qua các thành phần này:

  1. Request: Yêu cầu HTTP đến server NestJS.
  2. Middleware: Các middleware toàn cục hoặc cụ thể của Express/Fastify được thực thi trước tiên (nếu có).
  3. Guards: Các Guards được thực thi để kiểm tra quyền truy cập. Nếu một Guard trả về false, yêu cầu sẽ bị chặn.
  4. Interceptors (Pre-handler): Các Interceptor chạy trước khi route handler được gọi, cho phép sửa đổi request hoặc ghi log.
  5. Pipes: Các Pipes được thực thi để chuyển đổi hoặc xác thực dữ liệu của các tham số đầu vào.
  6. Route Handler: Phương thức của Controller được gọi để thực thi logic nghiệp vụ.
  7. Service/Provider: Controller gọi các phương thức từ các Service/Provider để xử lý logic chính và tương tác với dữ liệu.
  8. Interceptors (Post-handler): Các Interceptor chạy sau khi route handler trả về kết quả, cho phép sửa đổi phản hồi hoặc ghi log.
  9. Exception Filters: Nếu có bất kỳ ngoại lệ nào xảy ra trong quá trình này và không được xử lý, Exception Filters sẽ bắt và định dạng lại phản hồi lỗi.
  10. Response: Phản hồi cuối cùng được gửi về cho client.

Kết Luận

NestJS cung cấp một kiến trúc mạnh mẽ và có cấu trúc rõ ràng, giúp bạn xây dựng các ứng dụng phía máy chủ hiệu quả và dễ bảo trì. Việc hiểu rõ các thành phần cơ bản như Modules, Controllers, Providers, Pipes, Guards, Interceptors và Exception Filters là chìa khóa để tận dụng tối đa sức mạnh của framework này.

Bằng cách áp dụng các nguyên tắc thiết kế tốt và cấu trúc module hóa, NestJS không chỉ giúp bạn viết code sạch hơn mà còn tăng cường khả năng kiểm thử, mở rộng và hợp tác trong các dự án lớn. Hãy bắt đầu hành trình của bạn với NestJS ngay hôm nay và khám phá tiềm năng không giới hạn của nó!

Bạn có câu hỏi nào về các thành phần này không? Hãy để lại bình luận bên dưới nhé!

Previous Post

`useState` trong React: Nền Tảng Quản Lý Trạng Thái cho Component Hàm

Related Posts

Blog

`useState` trong React: Nền Tảng Quản Lý Trạng Thái cho Component Hàm

by Nguyen Pham
02/09/2025
Hướng Dẫn Cài Đặt và Chạy n8n Với Docker – Tự Động Hóa Công Việc Dễ Dàng
Blog

Hướng Dẫn Cài Đặt và Chạy n8n Với Docker – Tự Động Hóa Công Việc Dễ Dàng

by Nguyen Pham
02/09/2025
GPT OSS: Tương Lai Mã Nguồn Mở Cho AI Ngôn Ngữ
AI

GPT OSS: Tương Lai Mã Nguồn Mở Cho AI Ngôn Ngữ

by Nguyen Pham
17/08/2025
Blog

Facebook, Instagram bất ngờ sập trên diện rộng, liên tục đăng xuất người dùng!

by Nguyen Pham
05/03/2024
Xây dựng todo app với smartcontract
Blog

Web3 là gì?

by Nguyen Pham
30/06/2023
Blog

Chạy ứng dụng react native đầu tiên của bạn

by Nguyen Pham
29/06/2023
Load More
Please login to join discussion
Blog

Khám Phá Các Thành Phần Cơ Bản Kiến Tạo Nên Ứng Dụng NestJS Mạnh Mẽ

by Nguyen Pham
02/09/2025
0

Chào mừng các bạn đến với thế giới của NestJS – một framework Node.js tiến bộ, linh hoạt và cực...

Read more

`useState` trong React: Nền Tảng Quản Lý Trạng Thái cho Component Hàm

02/09/2025
Hướng Dẫn Cài Đặt và Chạy n8n Với Docker – Tự Động Hóa Công Việc Dễ Dàng

Hướng Dẫn Cài Đặt và Chạy n8n Với Docker – Tự Động Hóa Công Việc Dễ Dàng

02/09/2025
GPT OSS: Tương Lai Mã Nguồn Mở Cho AI Ngôn Ngữ

GPT OSS: Tương Lai Mã Nguồn Mở Cho AI Ngôn Ngữ

17/08/2025

Phân tích mã cổ phiếu VCB

26/04/2025

@2021 2k1.org [email protected]

No Result
View All Result
  • Home
  • Review
  • Applications
  • Computers
  • Gaming
  • Microsoft

© 2021 NData

Welcome Back!

Login to your account below

Forgotten Password?

Retrieve your password

Please enter your username or email address to reset your password.

Log In