Thông tin liên hệ
- 036.686.3943
- admin@nguoicodonvn2008.info
Dùng mẫu CQRS hợp lý, bạn có thể tạo ra những app NestJS sạch và dễ mở rộng hơn.

Một phương pháp tiếp cận lập trình NestJS phổ biến là xây dựng các dịch vụ điều khiển giao tiếp để truy cập dữ liệu. Thế nhưng, hình thức này không phải là mẫu thiết kế hợp lệ duy nhất trong NestJS. Bạn còn có nhiều mẫu khác, trong đó bao gồm CQRS.
CQRS là một mẫu thiết kế tách riêng các hoạt động đọc và viết của một ứng dụng. Sự phân tách này có thể giúp cải thiện khả năng mở rộng, hiệu suất và khả năng bảo trì.
Dưới đây là mọi điều bạn cần biết về CQRS và cách áp dụng nó khi xây dựng một NestJS API.
CQRS là chữ viết tắt của command-query responsibility segregation. Nó dùng các lệnh để tạo, update, xóa dữ liệu và các truy vấn để tìm nạp dữ liệu. Điều này giúp loại bỏ nhu cầu triển khai các lệnh gọi cơ sở dữ liệu của ứng dụng vào dịch vụ.
Nó cũng cho thấy sự phân biệt rõ ràng giữa logic truy vấn database cho dữ liệu và thực hiện các tác vụ khác trong ứng dụng.
Phương pháp CQRS hữu ích trong thiết kế hướng tên miền. Điều này cho phép bạn tách riêng các hoạt động liên quan tới cơ sở hạ tầng và logic domain trong ứng dụng. Bạn cũng có thể dùng nó để triển khai logic nghiệp vụ phức tạp, nhưng không nên áp dụng cho những app đơn giản hơn.
Bạn có thể dùng mẫu thiết kế CQRS trong một API đã dựng ở NestJS. Để tiếp tục, bạn cần cài Node.js trên máy tính và phiên bản NestJS mới nhất.
Giờ làm theo những bước, bạn sẽ tạo được một app viết blog đơn giản bằng mẫu thiết kế CQRS.
Tạp một dự án Nest mới cùng một nguồn post cho ứng dụng blog. Bạn có thể làm việc này bằng cách chạy lệnh sau trong terminal:
nest new nestjs-cqrs
nest g module posts
nest g controller posts
nest g service posts
Sau khi đã hoàn thành các bước kể trên, chạy lệnh terminal này để cài gói NestJS CQRS:
npm install --save @nestjs/cqrs
Thêm code sau vào file posts.service.ts để xác định class PostService.
// posts.service.ts
import { Injectable } from '@nestjs/common';
export interface Post {
title: string;
content: string;
}
@Injectable()
export class PostService {
private readonly posts: Post[] = [];
create(post: Post): Post {
this.posts.push(post);
return post;
}
findById(id: number): Post {
return this.posts.find(post => post.id === id);
}
}
PostService định nghĩa phương thức create và findById để tạo một bài đăng mới, đồng thời lấy bài đăng hiện tại từ ID của nó.
Bước tiếp theo để định nghĩa truy vấn và lệnh là cốt lõi của mẫu thiết kế CQRS.
Trong thư mục posts, tạo hai file mới: createPostCommand.command.ts & getPostQuery.query.ts. File lệnh này trông sẽ như sau:
// createPostCommand.command.ts
export class CreatePostCommand {
constructor(public readonly title: string, public readonly content: string) {}
}
Và file định nghĩ truy vấn trông sẽ như thế này:
// getPostQuery.query.ts
export class GetPostQuery {
constructor(public readonly id: number) {}
}
Sau khi thành công định nghĩa lệnh & truy vấn, bạn cần tạo các trình xử lý cho chúng. Một trình xử lý là một hàm chạy lệnh hoặc truy vấn, rồi trả về kết quả.
Tạo file handlers.ts trong thư mục post và dán code sau vào bên trong nó:
// handlers.ts
import { CommandHandler, ICommandHandler } from '@nestjs/cqrs';
import { CreatePostCommand } from './createPostCommand.command.ts';
import { PostService } from './post.service';
@CommandHandler(CreatePostCommand)
export class CreatePostHandler implements ICommandHandler<CreatePostCommand> {
constructor(private readonly postService: PostService) {}
async execute(command: CreatePostCommand) {
const { name, price } = command;
const post = await this.postService.create(title, content);
return post;
}
}
Trong cùng file handlers.ts, bạn có thể chỉnh sửa các lệnh nhập để bao gồm code như bên dưới và cho phép làm việc với các truy vấn. Sau đó, bạn có thể chạy trình xử lý truy vấn như code bên dưới:
// handler.ts
import { QueryHandler, IQueryHandler } from '@nestjs/cqrs';
import { GetPostQuery } from './getPostQuery.query';
import { PostService } from './post.service';
// query handler
@QueryHandler(GetProductQuery)
export class GetPostHandler implements IQueryHandler<GetPostQuery> {
constructor(private readonly postService: PostService) {}
async execute(query: GetPostQuery) {
const { id } = query;
const post = await this.postService.findOneById(id);
return post;
}
}
Bước cuối cùng là đăng ký lệnh và trình xử lý truy vấn bằng mô đun NestJS.
// post.module.ts
import { Module } from '@nestjs/common';
import { CommandHandlers, QueryHandlers } from 'handlers.ts';
import { PostService } from './post.service';
@Module({
providers: [
PostService,
...CommandHandlers,
...QueryHandlers,
],
})
export class PostModule {}
Code này đăng ký PostService, CommandHandlers, QueryHandlers trong mảng providers. Dùng toán tử mở rộng (…) để hợp nhất các mảng của trình xử lý query và command vào mảng providers.
Các lệnh đã đăng ký cùng trình xử lý truy vấn có thể được dùng ở những controllers. Code sau triển khai một trình điều khiển post chấp nhận các truy vấn HTTP và trả về phản hồi cần thiết.
// posts.controller.ts
import { Body, Controller, Post } from '@nestjs/common';
import { CommandBus } from '@nestjs/cqrs';
import { CreatePostCommand } from './createPostCommand.command.ts';
// controller that implements command
@Controller('posts')
export class PostController {
constructor(private readonly commandBus: CommandBus) {}
@Post()
async createPost(@Body() body: { title: string; content: string }) {
const { title, content } = body;
const command = new CreatePostCommand(title, content);
const post = await this.commandBus.execute(command);
return post;
}
}
Ở code trên, CommandBus chạy CreatePostCommand và tạo một bài đăng mới. Code này hiện cách triển khai một controller dùng truy vấn:
// posts.controller.ts
import { Controller, Get, Param } from '@nestjs/common';
import { QueryBus } from '@nestjs/cqrs';
import { GetPostQuery } from './getPostQuery.query';
@Controller('posts')
export class PostController {
constructor(private readonly queryBus: QueryBus) {}
@Get(':id')
async getPost(@Param('id') id: number) {
const query = new GetPostQuery(id);
const post = await this.queryBus.execute(query);
return post;
}
}
queryBus chạy GetPostQuery để nhận bài đăng chứa ID được cung cấp và trả về nó.
Sau khi hoàn thành tất cả các bước trên, bạn sẽ có một ứng dụng hoạt động đơn giản trong việc tạo & tìm nạp các bài viết trên blog.
Trên đây là tất cả những điều bạn cần biết về mẫu thiết kế CQRS. Hi vọng bài viết hữu ích với các bạn.
Nguồn tin: Quantrimang.com
Ý kiến bạn đọc
Những tin mới hơn
Những tin cũ hơn
TOP phần mềm AI bảo mật Internet tốt nhất hiện nay
Biến các ý tưởng thành giải thích trực quan, tương tác trong ChatGPT
TOP tiện ích mở rộng AI cho VS Code tốt nhất
Cách tạo website Portfolio miễn phí bằng ChatGPT
6 lựa chọn thay thế Visual Studio Code tốt nhất có tích hợp AI
Tạo form hỏi đáp tương tác trong vài phút và prompt chỉnh sửa
Hướng dẫn sử dụng Google Slides trong Claude
Hướng dẫn sử dụng Wolfram trong ChatGPT giải toán nâng cao
15 prompt AI thú vị cho ngày lễ Halloween
Hoàn thiện một thiết kế thực tế với ChatGPT + Canva
Cách kết nối ElevenLabs agent với hệ thống lên lịch Calendly
Cách tắt app chạy ngầm Windows 11, giảm ngốn RAM trên Win 11
Câu nói hay nhất về tháng 11, chào tháng 11
TOP công cụ AI tạo tài liệu tốt nhất
Cách xây dựng plugin trong ChatGPT
Hướng dẫn tự thiết kế website Portfolio bằng Claude
5 thiết kế ChatGPT + Canva đáp ứng hầu hết các nhu cầu trong cuộc sống
Những công cụ AI tốt nhất giúp giải toán dễ dàng
Hướng dẫn kết nối Booking.com với ChatGPT lên kế hoạch du lịch
15 prompt Gemini tạo ảnh sinh nhật đẹp nhất
Hướng dẫn cài đặt và sử dụng n8n trên Windows 11
Cách lập trình chuyên nghiệp hơn, dễ dàng hơn với tính năng Tệp trên Grok
Công thức tính diện tích hình Elip
Hướng dẫn ngắt kết nối ứng dụng trên ChatGPT
Hướng dẫn tạo đoạn hội thoại cho topic trên Twee
Bức tranh tổng quan về hỗ trợ khách hàng tích hợp AI
Cách sửa lỗi There Are Currently No Power Options Available Windows
Claude Code thực sự có giá bao nhiêu?
Hướng dẫn 8 cách mở bàn phím ảo trên Windows 10
Hướng dẫn tạo flashcard trên Canva AI