CQRS Nedir ? /Kullanıcı Yönetimi Projesi

Eren Yılmaz
4 min readMar 18, 2022

Selamlar, bir önceki makalede CQRS tasarım desenini kullanarak bir proje geliştireceğimizden ve bu konu dahilinde mediatr kütüphanesinden bahsetmiştik. Eğer konu hakkında bilginiz yoksa buradan ilgili makaleye göz atabilirsiniz.
Bu makalede artık CQRS tasarım deseninin ne olduğundan bahsedip, geliştireceğimiz projenin detaylarına ineceğiz. Projeyi nasıl uygulayacağımızı ve ne gibi yapılar kullanacağımızı konuşacağız. Sonraki iki makalede ise bu projenin kodlamasını gerçekleştireceğiz.

CQRS

CQRS, açılımı “Command Query Responsibility Segregation” olan, micro servis mimarilerin popüler olmasıyla oldukça yaygınlaşan bir tasarım desenidir. Projelerimizdeki “Command” ve “Query” işlemlerinin sorumluluklarının ayrılması gerektiğini savunur. Nedir bu command ve query?

Command, veriyi manipüle etme işlemlerine verilen genel isimdir. (Insert-Update-Delete)

Query : Veriyi okuma işlemlerine verilen genel isimdir. (Select)

Yani özetleyecek olursak cqrs, veri okuma işlemleri ile veri ekleme-silme-güncelleme işlemlerinin birbirinden ayrılması gerektiğini savunur.

Peki bu işlemleri nasıl ayırabiliriz? İşte burada birbirinden farklı yapılar kurabiliriz. Aynı proje içerisinde model bazlı ayırmadan tutun, command ve query projelerinin tamamen birbirinden ayrılması gibi yapılar kurulabilir.

Aynı proje içerisinde model bazlı ayırma yapısını uygularsak, proje yapısı aşağıdaki gibi olacaktır.

Aynı veri tabanı üzerinde dışarıdan alınan command ve query modellerinin “handler” adı verilen ilgili objelerde işlenerek gerekli işlemler gerçekleştirilir.

Command ve query projelerinin tamamen birbirinden ayrılması şeklindeki bir yapı, aşağıdaki gibi olacaktır.

Command ve query projeleri ve veri tabanları tamamen ayrı bir şekilde çalışmaktadır. Veri tabanları üzerinde senkronizasyonu ise bir message broker aracılığıyla gerçekleştirebiliriz. Bu yapı Eventual Consistency olacaktır. Ancak görebileceğiniz gibi, bu yapı uygulaması oldukça maliyetli olan bir yapı. Cqrs ne gibi avantajlar sunuyor da bu yapıyı kurmak işimize geliyor? Aslında micro service mimarilerin sağladığı bir çok avantajı bu yapı ile elde edebilmekteyiz.

Command ve query domainleri birbirinden ayırır. Tek bir projeye odaklanma imkanı sunar.

Ölçeklenebilirlik sunar. Birbirinden bağımsız command veya query projelerini ölçeklendirebiliriz.

Projelerde birbirinden bağımsız teknolojiler kullanabilmeye olanak tanır.

Cqrs üzerine konuştuğumuza göre, Artık geliştireceğimiz proje üzerine konuşabiliriz. Kullanıcı Yönetimini gerçekleştiren bir proje geliştireceğiz. Bu projeyi yukarıda 2. senaryoda bahsettiğimiz yapı gibi command ve query olacak şekilde iki ayrı yapıda geliştireceğiz. İki projede de mediatr ve automapper kütüphaneleri aktif olarak kullanacağız, ve .Net Core web api olarak geliştireceğiz.

Command Projesi

Command projemizde kullanıcı ve rol yönetim işlemlerini gerçekleştireceğiz. Burada insert-update-delete işlemlerimiz olacak. Gerçekleştirilecek işlemleri şöyle sıralayabiliriz;

Kullanıcı Oluşturma

Kullanıcı Hesap Doğrulama

Kullanıcı Güncelleme

Kullanıcı Silme

Role Oluşturma

Role Güncelleme

Role Silme

Kullanıcıya Rol Atama

Kullanıcı Adresi Güncelleme

Projemizde mimari olarak Onion Architecture kullanacağız. Veri tabanı olarak Postgresql veri tabanı kullanacağız. Tablo yapımız aşağıdaki gibi olacak.

Ayrıca, command tarafında gerçekleştirilen değişiklikleri query tarafında da senkkron halde tutmak için, bir message broker yapısına ihtiyacımız var. Mass transit framework ile birlikte rabbitmq kullanarak bu senkronizasyon işlemini gerçekleştireceğiz. Command tarafından query tarafına iletişimi event driven desing yöntemi ile sağlayacağız. Command tarafında oluşturulan eventleri redis üzerinde tutacağız.

Son olarak, multi thread yapılarda karşımıza çıkan tutarsızlıkları engellemek amacıyla bir yapı gerçekleştireceğiz. Örneğin bir thread üzerinde kullanıcı güncellemesi yapılırken, başka bir thread o kullanıcı üzerinde silme işlemi yapabilir. Böyle tutarsız durumlardan korunmak amacıyla, yine redisi kullanarak üzerinde bir lock objesi tutacak, ve basit bir distributed lock yapısı kuracağız.

Burada bahsettiğimiz postgresql, redis, rabbitmq ve sonrasında projemiz de dahil tüm yapıları docker üzerinde kuracak ve ayağa kaldıracağız.

Query

Query projemizin amacı kullanıcı, kullanıcı rolleri ve login geçmişi işlemlerini okumak olacak. Burada aynı zamanda command projemizde gerçekleştirilen işlemler sonucu fırlatılan eventleri yakalayarak query veri tabanımızı güncel tutacağız.

Listelenen verilerin cachelenmesi amacıyla burada da yine redis kullanılacaktır. Veri tabanı olarak mongodb kullanacağız. Query projemizde gerçekleştireceğimiz işlemler şunlardır;

Kullanıcıları Listeleme

Kullanıcı Detayını Getirme

Kullanıcıyı Rolleri ile Getirme

Kullanıcıyı Login Geçmişi ile Getirme

Rolleri Listeleme

Mongodb üzerinde koleksiyon yapımız aşağıdaki gibi olacaktır.

Böylece geliştireceğimiz projenin de detaylarından bahsetmiş olduk. Bir sonraki makalede artık command projemizin kodlamasını gerçekleştireceğiz. Tekrar görüşene kadar, kendinize çok iyi bakın.

--

--

Eren Yılmaz

Passionate Software Developer. Sharing Blogs and Projects Here. links.dev/erenyilmaz