Blog
Mert Özen'in yazılım geliştirme, backend, frontend ve DevOps üzerine blog yazıları.
Projection'lar: Inline, Async ve Live Projection ile Read Model Üretmek
Projection, event'leri belli bir soruya göre şekillenmiş bir read model'e çeviren fonksiyondur; Inline event'lerle aynı transaction'da, Async daemon ile arka planda çalışır, Live hiç saklanmaz. Bookstore stok defterinden stok rozeti, aylık stok hareketi ve kargo bekleyen rezervasyonlar; checkpoint, projection'ı değiştirip rebuild etmek, dead letter ve başarısız rebuild'in read model'i boşaltması.
Event Store ile Çalışmak: Marten ve PostgreSQL'de Append, Optimistic Concurrency ve Stream'ler
Event store'un temel sözleşmesi, bir stream'e yalnızca beklenen version'dayken event eklemektir; Marten bunu PostgreSQL'de (stream_id, version) unique index'i ve FetchForWriting ile sağlar. Marten 9 kurulumu, StartStream/Append, decider'ı FetchForWriting'e bağlamak, iki yazarın yarışı, stream id stratejileri, KurrentDB ve kendi tablonu yazmanın bedeli ve Türkçe culture'da bozulan event adları.
Decider Pattern ile Event-Sourced Aggregate: decide, evolve ve Given-When-Then Test'leri
Decider pattern, event-sourced bir modelin karar mantığını iki saf fonksiyona ayırır: Decide command ve state'ten yeni event'leri, Evolve state ve bir event'ten yeni state'i üretir. Stok defteri için C# 14 switch expression'larıyla bir decider, zamanı TimeProvider ile command'a taşımak, veritabanısız Given-When-Then test'leri ve OOP aggregate stiliyle karşılaştırma, gerçek test çıktılarıyla.
Event Sourcing Nedir? State Yerine Olanları Saklamak
Event Sourcing, son durumu değil olanları append-only bir event stream'inde saklayıp state'i bu event'lerden fold ederek türetmektir. Bookstore'un stok defteriyle rehydration, audit, geçmişe dönük okuma, expected version ile optimistic concurrency, event store'un neden bir message broker olmadığı, CQRS ile neden birlikte kullanıldığı ve gerçek maliyetleri.
Ayrı Read Model: Materialized View, Senkronizasyon ve Eventual Consistency ile Yaşamak
Ayrı read model, ekranın satırını domain event'lerinden önceden hesaplayıp saklamaktır; aynı transaction'da güncellenirse tutarlılık anlık kalır, ayrı bir veritabanında asenkron güncellenirse eventual consistency ile yaşamak gerekir. Inline projection, PostgreSQL materialized view, checkpoint'li asenkron projector, read-your-own-writes için position ile bekleme, idempotent update ve sıfırdan rebuild, gerçek çıktılarla.
Tek Veritabanında CQRS: Write Tarafında Aggregate, Read Tarafında Projection
Tek veritabanında CQRS, yazma tarafında aggregate'i EF Core'un change tracker'ıyla kaydedip okuma tarafında aynı tablolardan aggregate'e hiç dokunmadan projection yapmaktır. PlaceOrder ve CancelOrder command'larının ne döndürmesi gerektiği, ayrı ve düz bir read DbContext, SQL view üstünde Dapper ve query'nin state değiştirmediğini PostgreSQL'e read-only transaction ile söyletmek, gerçek SQL ve 25006 hatasıyla.
CQRS Nedir? CQS'ten Command Query Responsibility Segregation'a
CQRS, tek bir modeli yazma (command) ve okuma (query) için iki ayrı modele bölmektir; Meyer'in method seviyesindeki CQS ilkesini Greg Young model seviyesine taşıdı. Aggregate'in liste ekranına neden uymadığını gerçek bir derleme hatası ve sayımla gösteriyor, CQRS'in üç seviyesini, Event Sourcing ve MediatR'dan farkını ve Fowler'ın 'yalnız gerektiği yerde' uyarısını işliyoruz.
DDD'nin Evrimi ve Yaygın Yanlışlar: Blue Book'tan Dynamic Consistency Boundary'ye
DDD'nin en yaygın yanlışı, Blue Book'un sonunda kalan strategic design'ı atlayıp yalnızca entity, repository ve base class gibi tactical kelimeleri almaktır. Evans'ın 2003'teki kitabından DDD Reference'a, Vernon'ın aggregate kurallarına, EventStorming'e, Team Topologies ve Khononov'a, aggregate'i sorgulayan Dynamic Consistency Boundary'ye uzanan tarihçe; bellek içi bir DCB örneği ve seriden sonraki okuma rotası.
Uçtan Uca: Bookstore Ordering Context'ini Anemic CRUD'dan Zengin Modele Refactor Etmek
Anemic bir CRUD kodunu zengin modele taşımanın güvenli yolu, önce mevcut davranışı characterization test'lerle sabitleyip sonra dil, value object, aggregate sınırı, invariant ve domain event adımlarını her biri yeşil kalan ayrı commit'lerle atmaktır. Bookstore Ordering'i 11 commit'te dönüştürüyor, "3 al 2 öde" kampanyasıyla refactoring toward deeper insight'ı ve öncesi/sonrası metrikleri gerçek çıktılarla gösteriyoruz.
Domain Event'ler: Raise, Topla, SaveChanges'te Dispatch Et
Aggregate olanı geçmiş zamanlı, immutable bir domain event olarak yalnızca kendi listesine ekler; EF Core 10'un SaveChangesInterceptor'ı event'leri SaveChanges sırasında toplar, aynı transaction'daki handler'ları commit'ten önce, veritabanı dışına çıkan yan etkileri commit'ten sonra çalıştırır. Mediator'sız dispatcher, iç içe SaveChanges ve açık transaction tuzakları gerçek çıktılarla; integration event ve outbox farkı.
Domain Service, Application Service ve Anemic Domain Model
Davranış önce sahibi olan entity'ye ya da value object'e gider; hiçbirine doğal olarak ait olmayan, stateless bir domain hesabı domain service olur, yükleme-kaydetme-transaction ise ince bir application service'te kalır. Bookstore'da kopyalanmış kargo kuralını anemic service'lerden Order'a ve ShippingFeeCalculator'a taşıyıp policy, factory ve domain service'e repository inject etme tuzağını gerçek çıktılarla gösteriyoruz.
Aggregate Tasarımı: Consistency Boundary, Küçük Aggregate'ler ve Id ile Referans
Aggregate, gerçek invariant'ları tek bir transaction'da tutarlı tutan bir consistency boundary'dir; dışarıdan yalnızca root'a, diğer aggregate'lere de yalnızca id ile referans verilir. Vernon'un dört kuralını Bookstore'un Order ve StockItem aggregate'lerine uyguluyor, navigation property'nin katalog fiyatını sessizce değiştirdiği gerçek bir EF Core çıktısını, stok için eventual consistency'yi, 'kimin işi?' sorusunu ve Aggregate Design Canvas'ı işliyoruz.