
Yazılım geliştirme denildiğinde akla genellikle kod yazmak gelir. Oysa gerçek projelerde zamanın önemli bir kısmı kendi yazdığımız koddan çok, sahip olmadığımız sistemlerle uğraşarak geçer. API'ler, webhook'lar, yetkilendirme mekanizmaları, platform ayarları ve üçüncü parti servisler bazen iş mantığının kendisinden daha karmaşık hale gelebilir. Bu yazıda, bir entegrasyon sürecinde yaşadığım deneyim üzerinden, modern yazılım geliştirmede neden sistemleri birbirine konuşturmanın çoğu zaman kod yazmaktan daha zor olduğunu anlatmaya çalışıyorum.
Yazılım geliştirmeye ilk başladığım yıllarda mühendisliğin büyük ölçüde kod yazmaktan ibaret olduğunu düşünüyordum. Bir özellik gelir, ihtiyacı analiz eder, gerekli yapıları oluşturur ve çözümü geliştirirdim. O dönemde zor olan şeyin algoritmalar, mimari kararlar veya performans problemleri olduğunu sanıyordum.
Gerçek ürünler üzerinde çalışmaya başladıktan sonra ise farklı bir gerçekle karşılaştım. Çoğu zaman en çok vakit harcadığım yer kendi kod tabanım olmuyordu. Hatta bazen kendi yazdığım kod tarafında her şey düzgün çalışırken ürünün tamamı çalışmıyor oluyordu.
Bunun sebebi genellikle üçüncü parti servislerdi.
Bugün kullandığımız uygulamaların büyük kısmı aslında onlarca farklı sistemin bir araya gelmesiyle oluşuyor. Kimlik doğrulama başka bir servis tarafından sağlanıyor, bildirimler başka bir platformdan geliyor, ödeme sistemi farklı bir şirket tarafından yönetiliyor, mesajlaşma başka bir API üzerinden ilerliyor. Biz kendi uygulamamızı geliştiriyoruz gibi görünsek de gerçekte sürekli olarak başka sistemlerle iletişim kurmaya çalışıyoruz.
Ve çoğu zaman en zor kısım tam olarak burada başlıyor.
Yakın zamanda üzerinde çalıştığım kişisel bir projede bunu tekrar deneyimledim. Doğal dil üzerinden çalışan bir sistem geliştiriyordum ve teknik tarafta işler aslında oldukça iyi gidiyordu. Veritabanı hazırdı, API'ler çalışıyordu, AI modeli doğru çıktılar üretiyordu ve uygulama tarafında ciddi bir problem görünmüyordu.
Fakat sistemin en önemli noktalarından biri çalışmıyordu.
Gönderilen mesajlar uygulamaya ulaşmıyordu.
İlk refleksim muhtemelen çoğu geliştiriciyle aynıydı. Sorunun kendi kodumda olduğunu düşündüm. Logları kontrol ettim, endpoint'leri tekrar inceledim, deployment sürecini gözden geçirdim, environment değişkenlerini yeniden oluşturdum. Her şeyi tekrar tekrar test ettim.
İlginç olan şey şuydu:
Kod çalışıyordu.
Endpoint çalışıyordu.
Veritabanı çalışıyordu.
Ama ürün çalışmıyordu.
Böyle anlarda insanın aklına ilk gelen şey daha fazla kod yazmak oluyor. Oysa bazen ihtiyaç duyulan şey yeni kod değil, problemi doğru yerde aramak.
Bir süre sonra fark ettim ki aslında kendi uygulamamı debug etmiyordum. Başka bir platformun davranışlarını anlamaya çalışıyordum.
Bir ayar eksik miydi?
Yetkilendirme tarafında görünmeyen bir kısıtlama mı vardı?
Test ortamıyla gerçek ortam arasında farklı bir davranış mı oluşuyordu?
Webhook gerçekten tetikleniyor muydu?
Gönderilen istekler gerçekten ulaşıyor muydu?
Soruların hiçbiri kendi iş mantığımla ilgili değildi. Tamamı entegrasyon katmanıyla ilgiliydi.
Bu da bana tekrar şunu hatırlattı:
Bir ürün geliştirdiğimizde yalnızca kendi kodumuzdan sorumlu olmuyoruz. Aynı zamanda birlikte çalıştığımız sistemlerin davranışlarını da anlamak zorundayız.
Ve çoğu zaman bu sistemler bizim kontrolümüzde değil.
Modern servislerin çoğu oldukça kapsamlı dokümantasyonlara sahip. Bu kesinlikle büyük bir avantaj. Ancak gerçek hayatta dokümantasyonun anlattığı senaryo ile yaşadığınız senaryo her zaman birebir örtüşmeyebiliyor.
Dokümanda her şey birkaç adımda tamamlanıyor gibi görünürken gerçek hayatta farklı izinler, platform ayarları, test ortamı kısıtları veya beklenmeyen davranışlarla karşılaşabiliyorsunuz.
Bazen saatler boyunca kodu inceliyorsunuz.
Sonra sorunun tek bir platform ayarından kaynaklandığını fark ediyorsunuz.
Bazen onlarca log satırı okuyorsunuz.
Sonra sorunun bir yetki eksikliğinden kaynaklandığını öğreniyorsunuz.
Bazen de hiçbir şeyi değiştirmeden sadece doğru panel ekranını bulduğunuz için problem çözülüyor.
Yazılım geliştirme kariyerinde bir noktadan sonra bunun oldukça normal olduğunu kabul etmeye başlıyorsunuz.
Eskiden entegrasyon geliştirmeyi daha basit bir iş olarak görürdüm. Sonuçta birkaç API çağrısı yapmak ve gelen veriyi işlemekten ibaret gibi görünüyordu.
Bugün aynı fikirde değilim.
Çünkü iyi bir entegrasyon geliştirmek yalnızca teknik bilgi gerektirmiyor. Aynı zamanda karşı sistemin nasıl çalıştığını anlamayı da gerektiriyor.
Hangi durumda cevap üretir?
Hangi durumda sessizce başarısız olur?
Bir hata oluştuğunda nasıl davranır?
Webhook tekrar gönderilir mi?
Timeout durumunda ne olur?
Rate limit'e takıldığınızda sistem nasıl tepki verir?
Bu soruların çoğu sizin uygulamanızla ilgili değil. Karşı taraftaki sistemin karakteriyle ilgili.
Bu yüzden entegrasyon geliştirmek bana göre yalnızca kod yazmak değil, farklı sistemlerin davranışlarını öğrenmek anlamına geliyor.
Bu tarz süreçlerde fark ettiğim ilginç şeylerden biri de şu oldu:
Çoğu zaman bilgisayar başında yaptığım şey kod yazmak olmuyor.
Log okumak oluyor.
Sistemleri gözlemlemek oluyor.
İstekleri tekrar göndermek oluyor.
Farklı senaryoları izole etmeye çalışmak oluyor.
Çünkü problemi çözebilmek için önce problemin gerçekten nerede olduğunu anlamanız gerekiyor.
Bazen yanlış olan kod değildir.
Yanlış olan varsayımdır.
Ve yanlış varsayımları düzeltmek, yeni kod yazmaktan çok daha fazla mühendislik gerektirebilir.
Yazılım geliştirme dışarıdan bakıldığında kod yazma işi gibi görünür. Ancak gerçek ürünlerde zamanın önemli bir kısmı sistemleri birbirine bağlamakla geçer.
API'ler, webhook'lar, kimlik doğrulama servisleri, ödeme sistemleri, mesajlaşma platformları ve onlarca farklı entegrasyon katmanı artık modern yazılımların ayrılmaz bir parçası.
Bu yüzden bugün geriye dönüp baktığımda, en zor problemlerin büyük kısmının kendi yazdığım koddan kaynaklanmadığını görüyorum.
En zor problemler genellikle benim kontrol etmediğim sistemlerin kesişim noktasında ortaya çıkıyor.
Ve sanırım modern yazılım mühendisliğinin önemli bir kısmı da tam olarak burada başlıyor.
Eskiden iyi mühendis olmanın en önemli göstergesinin temiz kod yazabilmek olduğunu düşünürdüm. Bugün hâlâ bunun önemli olduğunu düşünüyorum ama artık tek başına yeterli olmadığını da biliyorum.
Çünkü modern yazılım geliştirmede yalnızca kendi sistemimizi anlamamız yetmiyor. Birlikte çalıştığımız diğer sistemlerin nasıl davrandığını da anlamamız gerekiyor.
Bazen en büyük zorluk algoritmalar değil.
Bazen en büyük zorluk, birbirini hiç tanımayan sistemlerin aynı dili konuşmasını sağlamak oluyor.