</>
⌕
Senior #cqrs#architecture#events#ddd

CQRS trong NestJS (@nestjs/cqrs): Command, Query, Event và khi nào nên dùng?

⚡ Trả lời nhanh

CQRS tách đường ghi (Command, đổi trạng thái) và đường đọc (Query, không side effect). @nestjs/cqrs cung cấp CommandBus, QueryBus, EventBus với handler riêng cho từng loại. Hữu ích khi nghiệp vụ phức tạp, read/write có yêu cầu khác nhau; với CRUD đơn giản thì thừa.

export class CreateOrderCommand { constructor(public readonly userId: number) {} }

@CommandHandler(CreateOrderCommand)
export class CreateOrderHandler implements ICommandHandler<CreateOrderCommand> {
  constructor(private repo: OrderRepo, private events: EventBus) {}
  async execute(cmd: CreateOrderCommand) {
    const order = await this.repo.create(cmd.userId);
    this.events.publish(new OrderCreatedEvent(order.id));
    return order.id;
  }
}

@QueryHandler(GetOrderQuery)
export class GetOrderHandler implements IQueryHandler<GetOrderQuery> {
  execute(q: GetOrderQuery) { return this.readModel.find(q.id); }
}

// controller: this.commandBus.execute(new CreateOrderCommand(1))
CommandQueryEvent
Ý nghĩaÝ định thay đổiCâu hỏiĐiều đã xảy ra
HandlerĐúng 1Đúng 10..N (@EventsHandler)
Trả vềTối thiểu (id)Dữ liệuKhông
  • Saga (RxJS) điều phối quy trình dài: bắt event rồi phát command tiếp theo.
  • Có thể tách read model (denormalized, cache, Elasticsearch) khỏi write model, đạt eventual consistency.
  • EventBus trong process không bền: crash là mất event; cần outbox + message broker nếu yêu cầu đảm bảo.
🃏 Ôn bằng flashcard