CQRS ( Command Query Responsibility Segregation) Nedir?

Abdullah Öztürk
3 min readJan 21, 2021

--

Herkese merhaba,

Bu makalemde CQRS pattern kullanımına, ne olduğuna, nasıl kullanıldığına ve ne zaman kullanılması gerektiği gibi konuların üzerinde duracağız.

Command Query Responsibility Segregation yani kısaca CQRS, isminden de anlayacağımız üzere komut ve sorguların ayrıştırılması prensibine dayanıyor. Bu prensibe göre “ bir metot, bir nesnenin durumunu değiştirmelidir yada geriye değer döndürmelidir. İkisini de aynı anda yapmamalıdır. ”

Command : Bir nesnenin durumunu değiştiren işlemlerdir.

Query : Tetiklenen bir olay sonucu geriye bir değer döndüren işlemlerdir.

Peki CQRS Ne Zaman Kullanılmalı?

  • Büyük sistemlerde yazma ve okuma sayısı arasında büyük fark olması mümkündür. ( Sosyal medya ve e-ticaret bu sistemlere örnektir. ) Bu durumda iki tarafı da bağımsız olarak scale edebiliriz.
  • Performans kritik düzeyde olduğunda CQRS ile okuma ve yazma kısımlarını optimize edebiliriz.
  • Karışık iş kurallarının olduğu bir senaryoda problemi komut ve sorgulara bölerek işi kolaylaştırabiliriz.
  • Geliştirme yaptığınız projede iki takım olarak çalışılacaksa yazma kısmına bir takım , okuma kısmına bir takım atayabiliriz. Ancak iki takımın da CQRS pattern hakkında bilgi sahibi olması beklenir.
  • Zaten hali hazırda event odaklı uygulama geliştiriyorsanız yazma tarafı, mevcut kısmı bir dizi olay olarak kaydettiğinden CQRS ile birlikte kullanılabilir.

CQRS Ne Zaman Kullanılmamalı?

  • Basit bir kullanıcı arayüzüne sahip bir uygulama geliştiriyorsanız ( CRUD işlemleri yapan bir uygulama gibi )
  • Eğer basit iş kurallarınız varsa CQRS implemente etmeniz kafa karıştırıcı olacaktır.
  • Tüm sistem için kullanılmamalıdır. Sistemin her bir parçası için CQRS desenini kullanmak zorunda değilsiniz.

.Net Core ile bu mimari deseni uygulamak istediğimizde karşımıza daha önce kullananların tahmin edebileceği gibi MediatR kütüphanesi çıkıyor. MediatR sayesinde bu mimari deseni uygulayabileceğiz. Öncelikle MediatR kütüphanesinin nasıl kullanıldığına girmeden mediator pattern nedir, ondan bahsedelim.

Mediator Pattern Nedir ?

Türkçesi arabulucu anlamına gelen bu pattern genel olarak nesnelerin yönetimi, aralarındaki iletişimin merkezi bir noktadan sağlanması ve yönetilmesi için kullanılır. En sık verilen örneklerden biri ise havaalanındaki uçakların birbiri arasındaki iletişimini sağlayan kule yapısıdır. Uçaklar birbirleri ile konuşmaz, kule ile iletişime geçer ve kule üzerinden gerekli işlemler yapılır.

Net Core Web Api Oluşturma

Projemizi yapmaya başlayalım. Terminalimi açıp sırasıyla aşağıdaki komutları girelim.

dotnet new webapi -n NetCoreMediatRExample
cd NetCoreMediatRExample
dotnet add package MediatR -version 9.0.0
dotnet add package MediatR.Extensions.Microsoft.DependencyInjection -version 9.0.0
code .

NetCoreMediatRExample isminde bir proje oluşturdum ve gerekli kütüphaneleri indirdikten sonra visual studio code editöründe açtım.

Startup.cs için gerekli düzenlemeler

Startup.cs üzerinde gerekli değişikleri yaptık. Şimdi direk ApiController kısmına bakalım ve kodlar üzerinden açıklamalar yapalım. (Projenin geri kalan kısmını aşağıdaki github linkinden inceleyebilirsiniz)

Entity olarak Player ve Game sınıflarını kullanalım. Command ve Query yapılarının birbirinden ayrılacağını bildiğimize göre PlayerQuery, PlayerCommand, GameQuery ve GameCommand sınıflarını oluşturalım.

GetPlayerQuery ve CreatePlayerCommand Sınıfları
GetGameQuery ve CreateGameCommand Sınıfları

Yukarıda sınıflarımızı tanımladık. Şimdi teker teker açıklayalım. Command ve Query sınıflarımız gördüğünüz gibi IRequest arayüzünden türetilmiştir. Bu arayüz ile beraber, eğer geriye bir değer döndürülecekse, sınıfımız için dönüş tipini belirtiyoruz.

Şimdi ise Handler sınıflarımızı yazacağız.

CreatePlayerHandler ve GetPlayersHandler Sınıfları

Tüm Handler sınıfları IRequestHandler arayüzünden türetilir ve ilk parametresi tetiklenecek model sınıfını, ikinci parametremiz ise dönüş tipini belirtmektedir. Örnek olması açısından sadece PlayerHandler sınıfını gösterdim. Son olarak Web API üzerinde kullanımını görerek sistemin işleyişini anlayalım.

PlayerController Sınıfı

IMediator arayüzünü enjekte ettikten sonra localhost:44347/api/player endpoint’ine gidildiğinde GetPlayersHandler, localhost:44347/api/players/1 endpoint’ine gidildiğinde ise GetPlayersHandler sınıfları tetiklenir ve Handle metodu içerisindeki işlemler gerçekleşir. Send metodu eğer getPlayersQuery tipinde bir request gönderirse bu durumda GetPlayersHandler sınıfı tetiklenecektir çünkü GetPlayersHandler handler sınıfının request tipi GetPlayersQuery’dir.

Örnek projeyi inceleyerek MediatR ve CQRS deseni arasındaki ilişkiyi daha iyi anlayabilirsiniz.

Örnek Proje Linki : .Net-Core-MediatR-CQRS

Kaynaklar :

--

--

Abdullah Öztürk
Abdullah Öztürk

Written by Abdullah Öztürk

Team Lead at P3S Bilgi Teknolojileri

Responses (1)