Son yıllarda mikroservis mimarisinin artan popülaritesine rağmen, bazı durumlarda monolithic (mikrosveris olmayan) uygulama geliştirme yaklaşımı da hala yaygın olarak tercih edilebiliyor. Monolithic uygulamaların da gereksinimlere göre hızlı adapte olabilmesi, ölçeklendirilebilmesi ve Java Spring Boot ile daha iyi yapılandırılabilmesi için, popüler Java uygulama geliştirme framework’ü Spring Boot framework’ünün geliştiricisi VMware, geçen sene Kasım ayında Spring Modulith 1.0’ı duyurmuştu.
Bu sene Ağustos ayında Spring Boot etkinliğinde, başlangıçta deneysel olarak geliştirilen Spring Framework ailesinin son üyesi Spring Modulith 1.0’ın artık deneysel olmaktan çıktığı ve tam desteklenen bir Spring projesi haline getirildiği duyuruldu. Spring Modulith’in deneysel olmaktan çıkması, framework’ün artık Visual Studio Code ve Spring Tool Suite gibi kod geliştirme editörleri tarafından da tanınır olması anlamına geliyor.
Peki Spring Modulith Ne Sağlıyor?
Java dilinde modülleri, birbiriyle yakın ilişkisi olan bir grup Java paketleri olarak düşünebiliriz. Aynı modülün içinde tanımlanan Java paketleri, birbiri tarafından erişilebilir ve okunabilir olabilirken, modül dışındaki paketler tarafından erişilemez yapılarak kodun tekrar kullanımı artırılabilmektedir (reusable).
Örneğin aşağıdaki gibi bir Java projesi yapısı düşünelim.
└─ src/main/java
├─ example
│ └─ Application.java
├─ example.inventory
│ ├─ InventoryManagement.java
│ └─ SomethingInventoryInternal.java
├─ example.order
│ └─ OrderManagement.java
└─ example.order.internal
└─ SomethingOrderInternal.java
Modül kullanılmadan yukarıdaki şekilde organize edilmiş bir Java uygulamasında example.inventory.SomethingInventoryInternal
sınıfı, diğer paketlerin içindeki Java sınıfları tarafından, özellikle “public
” olarak tanımlanmadıkça görünemez durumdadır. Ancak “public
” olarak tanımlanması durumunda da, diğer tüm paketler tarafından erişilebilir olacaktır.
Aslında tam da bu ihtiyaç için, Java 9 ile Java Platform Module System (JPMS) duyurulmuştu. JPMS, paketlerin de üzerinde, soyut bir gruplama katmanı tanımlamaktaydı. JPMS hakkında detaylı bilgi için şunu okuyabilirsiniz: A Guide to Java 9 Modularity (İngilizce).
Spring Modulith’i ise, JPMS kullanmadan “module” konseptini kullanabileceğiniz bir Spring framework’ü olarak düşünebilirsiniz. Uygulamanızda Modulith kullandığınızda, en üstte yer alan ana Java paketi altındaki tüm Java paketleri “by default” Java modülü olarak düşünülür ve ana paketin altında yer alan tüm paketler (yukarıdaki örnekte
order ve inventory
), bu modülün parçası olur. Bu paketler altındaki public
Java tipleri ise modülün API’sini oluşturur. Bu sayede, yukarıdaki örnekte yer alan example.order.internal
paketini public
hale getirmeden, aynı ana paket altındaki sınıflar tarafından erişilebilir yapabilirsiniz.
Bununla beraber, eğer Java uygulamanızda Java JPMS ile tasarlanmış bir modül kullanımı varsa, modüller arası internal paketlere erişim gibi tanımlarınız olsa da (yetkisiz erişim) kodunuz yine de compile edilirdi. Ancak Modulith, bu gibi yetkisiz erişimleri test aşamasında yakalar ve compilation hatası vererek uygulamanızın modülerliğini korur.
Modüller Arası İletişim
Spring Modulith ile, modüller arasında iletişim için Spring Framework uygulama event’leri kullanılabilir. Spring framework, uygulama event’lerinin Event Publication Registry (EPR) üzerinde kaydedilerek hedefine gönderilebilmesini garanti altına almaktadır (guaranteed delivery). EPR ile modüller arası iletişimde kullanılan bu event’ler, JPA, JDBC ve MongoDB aracılığıyla veritabanında saklanabilmektedir.
Modulith ile Asenkron Uygulamalarda Test
İletişimini asenkron eventler kullanarak gerçekleştiren Java uygulamaları için standart Java test yöntemleri ile test kodu geliştirmek zor olabilir. Bu nedenle Modulith kapsamında, Java test’lerine dahil edilebilen, event’inizin başlangıcını ve beklediğiniz cevabı tanımlayarak test oluşturabildiğiniz Integration Test senaryoları da sağlanmakta.