CQRS ile Okuma ve Yazmayı Ayırınca Ne Değişiyor
Bir apartman yönetim sisteminde sorgular yüzde 40 hızlandı.
Mert Celal Yılmaz · Full Stack Developer · Güncellendi:
Bir API büyüdükçe genellikle ilk tıkanma noktası, okuma ve yazma işlemlerinin aynı kod yolundan geçmesi oluyor. Clean Architecture bunu katmanlara ayırarak çözmeye çalışır: iş kuralların veritabanından, framework'ten bağımsız kalır. CQRS bir adım öteye geçip okuma (query) ve yazma (command) işlemlerini birbirinden tamamen ayırıyor. MediatR de .NET tarafında bu command ve query'leri doğru handler'a yönlendiren küçük ama işlevsel bir kütüphane.
Ben çok kiracılı API'lerde CQRS ve MediatR'ı bir arada kullanıyorum. Her command ya da query kendi handler'ında yaşıyor, controller sadece isteği MediatR'a yönlendiriyor. Bu ayrım özellikle veri büyüdükçe ve tenant sayısı arttıkça işe yarıyor.
Bir apartman yönetim sisteminde bunun somut karşılığını gördüm: iki kişilik bir ekiple yürüttüğümüz bu projede CQRS ile read/write ayrımına gittikten sonra sorgu performansında yüzde 40'lık bir iyileşme elde ettik. Otel rezervasyon AI asistanında ve solo olarak geliştirdiğim bulut tabanlı doküman yönetim sisteminde de aynı Clean Architecture ve CQRS düzenini kurdum.
Katman sayısı artıyor gibi görünse de, kod büyüdükçe nereye bakman gerektiğini bilmek asıl zaman kazandıran şey.
MediatR'ın gerçek faydası sadece command ya da query'yi doğru handler'a yönlendirmesi değil, pipeline behavior dediği ara katmanları devreye sokabilmesi. Validation, loglama, transaction yönetimi gibi her command'da tekrar eden işleri handler'ın içine yazmak yerine IPipelineBehavior üzerinden tek bir yerde tanımlıyorsun; her yeni command otomatik olarak bu davranışlardan geçiyor. Böylece bir handler sadece kendi iş mantığına odaklanıyor, validation ya da loglama kodu her seferinde kopyala-yapıştır olmuyor.
CQRS deyince akla hemen ayrı bir okuma veritabanı ya da event sourcing geliyor, oysa ikisi de zorunlu değil. Kurduğum projelerde okuma ve yazma aynı veritabanını kullanıyor, sadece kod tarafında ayrı modeller ve ayrı sorgularla ilerliyorlar. Küçük, CRUD ağırlıklı bir iç araç için bu ayrımı baştan kurmak fazladan dosya ve katman demek; birkaç ekranlık, tek kişilik bir işte CQRS'i tam anlamıyla kurmak kazandırdığından daha fazla karmaşıklık getirebilir.