Command Query Responsibility Segregation — Yazma (Write) və Oxuma (Read) əməliyyatlarını tamamilə ayrı modellərə/bazalara bölmək.
Oxuma ilə yazma tələbləri fərqlidir: Oxuma sürətli olmalıdır (denormalized), Yazma isə tutarlı (normalized). Onları ayırmaq hər ikisini optimallaşdırır.
Command tərəf: validasiya, biznes qaydaları, master DB-yə yazır. Query tərəf: denormalized replica/view-dan oxuyur — çox sürətli.
Axon Framework, Kafka + Elasticsearch, PostgreSQL + MongoDB, MediatR (.NET).
POST /orders → Normalized DBGET /orders → Denormalized View@Service
public class OrderCommandService {
private final OrderRepository orderRepo; // PostgreSQL (Normalized)
private final EventPublisher eventPublisher;
public void createOrder(CreateOrderCommand cmd) {
// 1. Validasiya
if (cmd.getAmount() <= 0) throw new InvalidOrderException();
// 2. Master DB-yə yaz (Normalized)
Order order = orderRepo.save(new Order(cmd));
// 3. Query tərəfə Event göndər (Sync)
eventPublisher.publish(new OrderCreatedEvent(order));
}
}
@Service
public class OrderQueryService {
private final OrderViewRepository viewRepo; // MongoDB (Denormalized)
// Event-i dinlə, View-u yenilə
@EventHandler
public void on(OrderCreatedEvent event) {
OrderView view = new OrderView(event.getId(), event.getTotal(),
event.getCustomerName()); // Flat, denormalized
viewRepo.save(view);
}
// Oxuma — sürətli, JOIN yoxdur
public List<OrderView> getOrders() {
return viewRepo.findAll(); // MongoDB-dən birbaşa
}
}