26 Aralık 2024 Perşembe

Mikroservis Yazı Serisi 9 - Backward Compatibility

     Selamün Aleyküm Arkadaşlar,

     Serinin dokuzuncu yazısında Backward Compatibility (geriye uyumluluk) konusuna bakıyor olacağız. Geriye uyumluluk sadece mikroservislerde değil, monolit yapılarda da önemli bir yere sahip bir kavramdır. Dış servisler veya sistemler tarafından kullanılan uçlarımızda bir değişiklik yaptığımızda önceki halini bozmayacak bir şekilde geliştirilmesi gerekiyor. Hazırsak başlayalım.

    Öncelikle konuyu kısaca monolit yapılar için ele alarak başlayalım. Bir modül veya yapıda kullanılan bir endpoint veya DTO birçok yer tarafından kullanılabilir, burada meydana gelen bir "breaking change" diğer tarafları da etkileyebilir. Bütün sistemi her zaman aynı anda güncellemek mümkün olmayacağından burada yapılan değişikliklerin geri uyumlu olması lazım. Bununla birlikte dış bağımlılıklar ve istemcinin kullandığı noktalar da bu kapsama girer.

    Yukarıda bahsedilen konular mikroservis yapıları için de geçerlidir. Ancak mikroservis yapılarda birçok servis olacağı için bunların birbirleriyle konuşması ve diğer ekipleri de ilgilendireceği için yapılan geliştirme çok daha kritik olabilmektedir. Bununla birlikte monolit yapının tersine buradaki aksaklık belirli bir servisi etkilerken, monolit yapıda yapılan değişiklik tüm sistemi etkileyebilir. 

    Peki geri uyumluluk diyoruz, buna sebebiyet veren durumların "breaking change" olduğunu ifade ettik. Kısaca eskiden sisteme gelen bir istemci yapılan değişiklikten sonra sistemden beklediği cevabı alamıyordur. Parametre sayısının veya tipinin değişmesi, DTO'dan herhangi bir alanın silinmesi ve zorunlu hale getirilmesi buna örnek olarak gösterilebilir. Yapılan her değişiklik de "breaking change" manasına gelmez bunu da hatırlatmakta fayda var.

    API Versiyonlama, herhangi bir endpoint'te yapılan bir geliştirme "breaking change" (kırılganlığa) sebep oluyorsa endpoint'lerimizi değiştirmek yerine onları versiyonlayabiliriz. Sistemi tasarlarken buna uygun olarak geliştirmek gerekir.  Bunu yapmanın farklı yöntemleri olsa da önemli olan temel mantık olduğu için ayrıntılara girmiyoruz.

    Kontrakların iyi tasarlanması (DTO), yukarıda da berilttiğimiz gibi DTO'lardan herhangi bir alan silinmesi, bir alanın zorunlu hale getirilmesi buna sebebiyet verir. Buna çözüm olarak yeni alanların eklenirken varsayılan olarak değer atanması, zorunlu olmayan alanların eklenmesi ya da kullanılmayan alana "deprecated" demek de çözüm olabilir.

    Tolerant Reader, istemci tarafından alınan bir önlemdir. Gelen veride beklediğinin dışında alanlar eklenmiş olsa da eski istemciler doğru bir şekilde çalışmaya devam edebilir.

    Feature Flag, yeni eklenen özellik (feature) hayata alındıktan sonra o özelliği kapatıp açılabilmesine denir. Yapılan testlerden dahi kaçsa ortaya çıkan sorun sonrası bu flag'ı kapatarak sistemin eskisi gibi çalışması hedeflenir.

    A/B testleri, hayata geçirdiğimiz bir özelliği, bütün kullanıcılara/istemcilere açmak yerine öncelikle belirli bir gruba açmayı hedefler. Her şey yolunda gittiyse yavaş yavaş tüm herkese açılır. Bir aksilik olursa geri dönüş planları hayata alınır.

    Tüm bu çözümler kulağa hoş gelse de tahmin edeceğiniz üzere bunların da birlikte getirdiği maliyetler oluyor. Bunlardan bazılarını ele alacak olursak;

  • Eski ve yeni sürümler nedeniyle test süreçleri ve buradaki maliyetler artmaktadır. 
  • Doğal olarak kodun kendisi de karmaşıklaşmaktadır, bunun da bakım maliyeti artmaktadır.
  • Sürüm yönetimi de zorlaşmaktadır.
  • Feature flag'ların bakımı yapılmadığı takdirde kodun okuması zorlaşmaktadır (Bunu birebir yaşıyoruz. Belirli aralıklarla kontrol etmekte fayda var. İkinci madde ile de direkt bağımlı. Ayrıca testleri yaparken ff açık mı kapalı, test ve prod ortamları senkron mu gibi konuları da ihmal etmemek lazım.).
    Özetle önerilen çözümlerin faydası olsa da bunları belirli bir standartta yaparak ve gerektiğinde bunlar refactor ederek veya kullanılmayan yapıları kaldırarak burada oluşabilecek maliyetleri de düşürmenin faydaları olacaktır. Ayrıca yukarıda da belirttiğimiz gibi "Deprecated" attribute, dokümanları güncel tutarak ve semantic versiyonlama yaparak oluşabilecek maliyetleri indirgeyebiliriz.

    Yazıyı birer ayet-i kerim ve hadis-i şerif ile bitirelim

"Onların işleri, aralarında şûra (danışma) iledir." (Şûrâ Suresi, 42:38)

"Akıllı kişi, nefsini kontrol eden ve ölümden sonrası için çalışandır. Aciz kişi ise, nefsinin hevasına uyan ve Allah’tan (hiçbir gayret göstermeden) temennilerde bulunandır."                                                                                 (Tirmizî, Kıyamet, 25; İbn Mâce, Zühd, 31)

Hiç yorum yok:

Yorum Gönder