Traditional Monolith
Öncelikle Traditional Monolith yaklaşımından bahsedelim. Bu yaklaşım katmanlara odaklanır. UI, Business ve Data olmak üzere üç katman içerir. Bir projedeki tüm özellikler dikey olarak bu katmanlara ayrılır. Bu üç katman arasında Business katmanı, tüm modüllerin business logic'ini içeren katmandır. Her bir modül, diğer modüllerin business logic'ini bilir ki buna tightly coupled diyebiliriz.
Modular Monolith
Modular Monolith'in ana odak noktası modülleri ayırmaktır. Her modülün kendi katmanları vardır (Domain, Infrastructure ve API vb.). Böylece farklı veritabanı çözümleri kullanabilirler. Öte yandan modüller kendi business logic'lerini birbirleriyle paylaşmazlar. Birbirleriyle sync veya async yöntemleriyle haberleşirler. Loosely coupled bir yapısı vardır.
Modular Monolith'in tek bir giriş noktası vardır. Bu nedenle, Modular Monolith uygulayan uygulamalar yatay olarak ölçeklenemez. Ayrıca modüller fiziksel olarak değil mantıksal olarak ayrılmıştır. Yani Modular Monolith fiziksel olarak dağıtılmış bir yapıya sahip değildir. Fiziksel olarak ayırmak istiyorsak, microservice yaklaşımını uygulamamız gerekir.
Traditional Monolith kötü bir seçim değil ama yapısı gereği big ball of mud haline dönüşme olasılığı yüksek. Microservice'e geçişi de oldukça zordur. Öte yandan, Modular Monolith kolayca microservice'e geçebilir. Uygulamanız internet ölçeğinde yayınlanacaksa, microservice iyi bir seçimdir. Ancak uygulamanız yalnızca bir kuruluş içinde yayınlanacaksa Modular Monolith daha iyi bir seçenektir.
Modular Monolith'de İletişim
Bir e-ticaret uygulamasındaki bir sipariş sistemini ele alalım. Bir sipariş sistemindeki temel modüller Inventory, Order ve Payment'dır. Satın alma sürecinde sipariş alınır, stok kontrol edilir ve ödeme alınır. Bir ürün stokta yoksa veya ödeme alınamadıysa sipariş iptal edilir. Peki Modular Monolith'de böyle bir iletişim nasıl oluyor?
İletişim için iki yaklaşım (sync, async) vardır. Sync yaklaşımında, her modül bir interface sunar. Bu interface'ler, modüllerin Shared katmanlarında tanımlanır. Inventory modülü, ReserveStock, ReleaseStock yöntemlerine sahip IInventoryService interface'ini sunar. Aynı şekilde Payment modülü, MakePayment yöntemine sahip IPaymentService interface'ini sunar. Order modülü bu interface'ler aracılığıyla diğer modüllerle haberleşir.
Async yaklaşımında, her modül event'ler yayınlar. Bu event'ler, modüllerin Shared katmanlarında tanımlanır. Order modülü, OrderReceived event'ini yayınlar. Inventory modülü, ReserveStock, OutOfStock ve ReleaseStock event'lerini yayınlar. Aynı şekilde, Payment modülü MakePayment, PaymentMade ve PaymentFailed event'lerini yayınlar. Her modül ilgili olaylara abone olur. Böylece iletişim, message broker aracılığıyla gerçekleşir.
Async iletişiminde iki yaklaşım (choreography, orchestration) vardır. Hangisinin tercih edildiği önemli değil. Bu senaryo için choreography daha verimli olduğu için bunu tercih ettim.
Solution'ın Yapısı
Bootstrapper, projenin giriş noktasıdır. Yani bir WebApp.
Her modülün standart olmayan kendi katmanları vardır. Onion or Hexagonal mimarisi uygulayabilirsiniz.
Shared.Abstractions : Modules.Core ve Modules.Infrastructure tarafından kullanılır. Interface'ler, DDD, CQRS vb. gibi abstraction'ları içerir.
Shared : Cross-cutting concern için kullanılır. Ayrıca abstraction'ların implementasyonlarını da içerir.
Ecommerce.Inventory : Bir class library. Inventory modülünün controller'larını veya endpoint'lerini içerir. İletişim için async yöntemini kullanmayı düşünüyorsanız, consumer'ları (ReserveStockConsumer, ReleaseStockConsumer vb.) bu katmana ekleyebilirsiniz.
Ecommerce.Inventory.Core : Inventory modülünün domain veya business logic'ini içerir. Dilerseniz bu katmanı Application ve Domain olmak üzere ikiye ayırabilirsiniz.
Ecommerce.Inventory.Infrastructure : Inventory modülünün external servislere veya veritabanı, message queue vb. bileşenlere bağlandığı yerdir.
Ecommerce.Inventory.Shared : Bazı class'ları (OutOfStock, StockReserved vb.) diğer modüller ile paylaşmak ve diğer modüllerin bu class'ları kullanmasına izin vermek için kullanılır.
Özet
Projenizin big ball of mud haline gelmesini istemiyorsanız ve projenizin internet ölçeğinde yayınlanmasına ihtiyacı yoksa veya projenizi daha sonra bir microservice mimarisine dönüştürme olasılığınız varsa Modular Monolith kullanmak iyi bir seçimdir.
Örnek projelere Github adresimden ulaşabilirsiniz.
Vesselam.
Yorum bırak
Yanıtla
Yanıtlamayı iptal et