Yazılım geliştirirken kod yazmak çoğunlukla en heyecan verici ve görünür kısım olsa da, gerçek ustalık asıl olarak sistemin mimarisini kurgulamakta gizlidir. Ben de uzun süre sadece fonksiyonellikleri kodlamaya odaklandım: varlıkları oluşturmak, kontrolörleri yazmak, veritabanını bağlamak ve formları doğrulamak.
Ancak Web Uygulama Geliştirme dersi kapsamındaki proje çalışması, geliştirdiğimiz klinik yönetim sistemini MVP olarak başlatıp, zamanla çok kiracılı bir SaaS platformuna dönüştürme sürecinde mimari kararların kod yazmaktan çok daha önemli olduğunu fark etmemi sağladı. Proje akademik bir zorunluluktu ancak gerçek dünya koşullarını taklit etmeye çalıştığımız için iş kısıtları, bütçe sınırları, güvenlik gereksinimleri ve gelecekteki büyüme senaryolarını da hesaba katmak zorunda kaldık. En önemli çıkarım şu oldu: En iyi mimari, ürünün o anki ihtiyaçlarına en iyi cevap verebilen mimariydi.
Başlangıçta Aşırı Tasarım Yapmaktan Kaçınmak
Sistem tasarlarken ilk dürtümüz doğrudan karmaşık bir mimariye yönelmekti: microservisler, olay odaklı iletişim, kuyruk sistemleri, Kubernetes ortamı, çoklu veritabanları ve bağımsız dağıtımlar. Ancak senaryoyu analiz ettiğimizde bu yaklaşımın gereksiz karmaşıklık eklediğini gördük. Sistem tek bir klinik için başlıyordu, bütçemiz kısıtlıydı ve gereksinimler hala netleşmemişti. Bu koşullarda microservis mimarisi kullanmak temelinden sorun yaratabilirdi: servisler arası iletişim, sözleşmeler, sürüm yönetimi, dağıtık gözlemleme, hata ayıklama zorluğu ve altyapı maliyetlerinde aşırı artış.
Bunun yerine katmanlı mimariyi tercih ettik ve sistemi tek bir süreç olarak dağıttık. Bu seçim, dağıtık bir sistemin karmaşıklığını üstlenmeden bile sorumlulukları net bir şekilde ayırmamıza olanak tanıdı:
- Sunum katmanı: API'ler, kontrolörler, DTO'lar ve kimlik doğrulama
- Uygulama katmanı: hasta yönetimi, randevu rezervasyonu ve klinik kayıtları gibi kullanım durumlarını barındırdı
- Altyapı katmanı: PostgreSQL erişimi, depo sınıfları ve WhatsApp entegrasyonunu sağladı
Bu yaklaşım, iyi organize edilmiş bir monolitin kötü bir mimari olmadığını gösterdi. Sadece problemi gerçek boyutuna uygun şekilde ele almamız gerekiyordu. Kararımızın ardındaki motivasyon, basitlikten kaynaklanan bir cehalet değil, projenin ilk aşaması için en makul çözümdü.
Tasarlarken Öngörülü Olmak, Gereksiz Karmaşıklık Eklememek
Bir diğer önemli ders de gelecekteki bazı kararların maliyetini doğru tahmin etmek oldu. Bazı değişiklikler başlangıçta çok ucuzken, daha sonra uygulanması son derece maliyetli hale gelebiliyor. Örneğin, sistem henüz tek bir klinik için çalışırken bile, veritabanı modeline TenantId alanını dahil ettik. Birden fazla kiracıya sahip olunmayacağı için gereksiz görünebilirdi, ancak platformun SaaS modeline evrilmesi durumunda bu alanın olmaması ciddi bir migrasyon riski yaratabilirdi.
Aynı şekilde Docker kullanımına erken karar verdik. MVP'nin basit bir sunucuda çalıştırılması mümkün olsa da, uygulamayı erken aşamada containerize etmek ileride farklı altyapılara kolayca taşıyabilmemizi sağladı. WhatsApp mesajlaşması için de soyut bir arayüz tanımladık: doğrudan bir sağlayıcıya bağlı kalmak yerine, IWhatsAppSender arabirimi sayesinde gelecekte sağlayıcı değiştirmek, geliştirme sırasında mesajları taklit etmek veya farklı entegrasyonlar eklemek çok daha kolay hale geldi.
Burada programlama ile tasarım arasındaki temel farkı anladım: Programlama anlık sorunu çözüyor; tasarım ise gelecekteki kapıları kapatmadan çözüm üretiyor.
Monolitik Sistemler Başarısız Olmaz, Senaryo Değişir
Projede microservislere geçiş otomatik olarak gerçekleşmedi. Bu değişim, iş modelinin dönüşümüne bağlıydı: sistem tek bir klinikten çok kiracılı bir SaaS platformuna evrildi. Bu dönüşüm beraberinde tamamen yeni gereksinimleri getirdi:
- Çoklu kiracı desteği ve verilerin izolasyonu
- Abonelikler, planlar ve kullanım sınırları
- Fatura ve ödeme sistemleri
- Yük dağılımındaki değişimler (randevu rezervasyonları gün boyunca dağılırken, WhatsApp hatırlatmaları yoğun saatlerde yoğunlaşabiliyor)
Bu noktada katmanlı mimari sınırlarını göstermeye başladı. Problem büyüdüğü için sistem de büyüdü. Eğer bildirim modülü yoğun kullanım yaşarsa, sadece o modülü ölçeklendirmek mümkün olmuyordu. Meta API'si yavaşladığında, WhatsApp'a bağımlı olmayan randevu rezervasyon işlemleri bile etkilenebiliyordu. Bu durum bizi şu kritik soruya yöneltti: Bir randevu rezervasyonu neden WhatsApp yavaşladığı için başarısız olsun?
Bu soruya yanıt ararken, farklı hizmetlerin birbirinden ayrılmasının gerekliliği ortaya çıktı. Randevu, Bildirim, Tıbbi Kayıt, Kimlik Doğrulama, Kiracı Yönetimi, Fatura ve Denetim modülleri birbirinden farklı sorumluluklara, değişiklik hızlarına ve ölçeklenme ihtiyaçlarına sahipti. Artık microservis mimarisi, sadece bir lüks değil, bir zorunluluk haline gelmişti.
Olay Odaklı Mimarilerle Yan Etkileri Kontrol Etmek
En karmaşık mimari zorluklarımızdan biri de senkron iletişimden olay odaklı bir mimariye geçiş oldu. Tamamen senkron bir modelde randevu rezervasyonu birçok ardışık HTTP çağrısını gerektiriyordu: veri doğrulama, hasta bilgisi sorgulama, kiracı yapılandırmasını kontrol etme, bildirim gönderme ve denetim kaydı oluşturma. Problem şu ki tüm bu servislerin aynı anda çalışabilir olması gerekiyordu. Bir servis başarısız olursa tüm işlem de başarısız oluyordu.
Olay odaklı mimaride ise süreç tamamen farklı çalışıyor. Randevu rezervasyonu hızlı ve güvenilir olmak zorundayken, bildirim gönderimi gibi yan işlemler sistemden bağımsız olarak gerçekleşebiliyor. Bu yaklaşımla sistem daha dayanıklı hale gelirken, herhangi bir bileşenin başarısızlığı tüm operasyonu durdurmuyor. Bu mimari değişiklik, sadece teknik bir tercih değil, aynı zamanda iş süreçlerinin güvenilirliğini doğrudan etkileyen stratejik bir karardı.
Sonuç: Mimariyi Projenin Evrimine Göre Şekillendirin
Ürün geliştirirken en yaygın hatalardan biri, gelecekteki tüm olası senaryoları öngörmeye çalışmaktır. Oysa en iyi mimari, ürünün o anki gereksinimlerine en iyi cevap verebilen ve büyümeyle birlikte evrilebilen mimari olmalıdır. MVP aşamasında basitlik ve hız önemlidir; büyüme evresinde ise ölçeklenebilirlik ve esneklik ön plana çıkar.
Klinik yönetim sistemini geliştirirken öğrendiğimiz en değerli ders, mimari kararların kod yazmaktan daha önemli olduğunu anlamaktı. İyi bir mimari, sadece bugünün ihtiyaçlarını karşılamakla kalmaz, aynı zamanda yarının belirsizliklerine karşı da koruma sağlar. Bu bakış açısıyla yola çıkan her geliştirici, sadece bir MVP değil, gelecekte başarıyla ölçeklenebilecek sağlam temeller üzerinde duran bir ürün inşa etmiş olur.
Yapay zeka özeti
Bir MVP projesi için basit bir mimari yeterli gibi görünse de, hızla büyüyen bir SaaS platformuna dönüşmek mimarinin baştan öngörülmesini gerektiriyor. Küçükten başlayıp ölçeklendirirken yapılan hatalardan ders çıkarmak, başarılı bir ürün yolculuğunun anahtarı.