Aikido

Genel API sözleşmelerinin ihlal edilmesi nasıl önlenir: geriye dönük uyumluluğu koruma

Sürdürülebilirlik

Kural

Genel API sözleşmelerini ihlal etmekten kaçının.
Mevcut istemci isteklerini bozacak genel API uç noktası değişiklikleri
uyumsuzluk yaratan değişikliklerdir.  
API sözleşmesini bir söz olarak düşünün;
— istemciler
ona bağımlı hale geldikten sonra bunu değiştirmek kodlarını bozar.

Desteklenen diller: PHP, Java, C#, Python, JavaScript, TypeScript

Giriş

Genel (public) API'ler, servisiniz ile bunu kullananlar arasındaki sözleşmelerdir. İstemciler bir uç noktanın (endpoint) istek formatına, yanıt yapısına veya davranışına bağımlı hale geldiğinde, bu yapıyı değiştirmek onların kodunu bozar. Uyumsuzluk yaratan (breaking) değişiklikler, tüm istemcilerin aynı anda güncelleme yapmasını zorunlu kılar; ancak istemcileri kontrol etmediğiniz durumlarda bu genellikle imkansızdır. Mobil uygulamalar zorunlu olarak güncellenemez, üçüncü taraf entegrasyonların migrasyon süresine ihtiyacı vardır ve eski (legacy) sistemler asla güncellenmeyebilir.

Neden önemli?

İstemci kesintileri ve güven kaybı: Uyumsuz API değişiklikleri, prodüksiyon ortamındaki istemci uygulamalarında ani hatalara neden olur. Kullanıcılar hatalar, veri kayıpları veya tam servis kesintileri yaşar. Bu durum, API sağlayıcıları ile tüketicileri arasındaki güvene zarar verir ve kararlı API'lerin kararlı kalacağına dair zımni sözleşmeyi ihlal eder.

Koordinasyon maliyetleri: Uyumsuz değişiklikleri birden fazla istemci ekibi arasında koordine etmek masraflı ve yavaştır. Her ekibin kodu güncellemek, değişiklikleri test etmek ve devreye almak için zamana ihtiyacı vardır. Bilinmeyen istemcilere (mobil uygulamalar, üçüncü taraf entegrasyonlar) sahip genel API'ler için koordinasyon imkansızdır.

Sürüm çoğalması: Kötü yönetilen uyumsuz değişiklikler, aynı anda birden fazla API sürümünün bakımının yapılmasına yol açar. Her sürüm ayrı kod yolları, testler, dokümantasyon ve hata düzeltmeleri gerektirerek bakım yükünü katlanarak artırır.

Kod örnekleri

❌ Kural dışı:

// Version 1: Original API
app.get('/api/users/:id', async (req, res) => {
    const user = await db.users.findById(req.params.id);
    res.json({ id: user.id, name: user.name });
});

// Version 2: Breaking change - renamed field
app.get('/api/users/:id', async (req, res) => {
    const user = await db.users.findById(req.params.id);
    res.json({
        id: user.id,
        fullName: user.name  // Breaking: 'name' renamed to 'fullName'
    });
});

Neden yanlış: name alanını fullName olarak yeniden adlandırmak, name alanını bekleyen tüm mevcut istemcileri bozar. response.name değerine erişen istemci kodu undefined alarak hatalara yol açar. Bu değişiklik, tüm istemcilerin aynı anda güncelleme yapmasını ya da hata almasını zorunlu kılar.

✅ Kurallara uygun:

// Version 2: Additive change - keeps old field, adds new
app.get('/api/users/:id', async (req, res) => {
    const user = await db.users.findById(req.params.id);
    res.json({
        id: user.id,
        name: user.name,           // Keep for backward compatibility
        fullName: user.name        // Add new field (deprecated 'name')
    });
});

// Or use API versioning
app.get('/api/v2/users/:id', async (req, res) => {
    const user = await db.users.findById(req.params.id);
    res.json({ id: user.id, fullName: user.name });
});

Neden önemli: Eski olanı tutmak name alanı, geri dönüştürülebilirliği korurken ekleme yapar fullName yeni istemciler için. Alternatif olarak, yeni sürümlendirilmiş bir uç nokta (endpoint) oluşturmak (/api/v2/) mevcut istemcileri etkilemeden kırıcı değişiklikler (breaking changes) yapılmasına olanak tanır ve hâlâ şunu kullanan /api/v1/.

Sonuç

API'leri eklemeli değişikliklerle geliştirin: yeni alanlar, yeni uç noktalar (endpoints) ve isteğe bağlı parametreler ekleyin. Kırıcı değişiklikler kaçınılmaz olduğunda, eski ve yeni sürümleri aynı anda çalıştırmak için API sürümlendirmesini kullanın. Kaldırmadan önce eski alanları net zaman çizelgeleri ve geçiş kılavuzlarıyla kullanımdan kaldırın (deprecate edin).

Sık Sorulan Sorular

Sorularınız mı var?

Hangi değişiklikler kırıcı (breaking) kabul edilir?

Yanıt parametrelerinden alanların kaldırılması, alanların yeniden adlandırılması, alan türlerinin değiştirilmesi (string'den number'a), isteğe bağlı parametrelerin zorunlu hale getirilmesi, mevcut durumlar için HTTP durum kodlarının değiştirilmesi, kimlik doğrulama gereksinimlerinin değiştirilmesi ve hata yanıtı formatlarının güncellenmesi. Yeni zorunlu istek parametreleri eklemek veya uç noktaları tamamen kaldırmak da kırıcı değişikliklerdir.

İstemcileri bozmadan yeni zorunlu alanları nasıl ekleyebilirim?

Yeni alanı başlangıçta mantıklı bir varsayılan değerle isteğe bağlı (optional) yapın. Değişikliği belgelendirin ve istemcilere bunu benimsemeleri için zaman tanıyın. Yeterli süre geçtikten sonra (halka açık API'ler için 6-12 ay), alanı yeni bir API sürümünde zorunlu hale getirin. Sürümlendirme yapmadan mevcut isteğe bağlı alanları asla zorunlu hale getirmeyin.

API sürümlendirme ile kullanımdan kaldırma (deprecation) arasındaki fark nedir?

Sürümlendirme, eskisinin yanında yeni bir uç nokta (/v2/users) oluşturarak ikisinin bir arada var olmasına olanak tanır. Kullanımdan kaldırma (deprecation), eski bir uç noktayı veya alanı, nihai kaldırma için bir zaman çizelgesi belirleyerek ve işlevsel tutarak eskimiş olarak işaretler. Büyük değişiklikler için sürümlendirmeyi, küçük özelliklerin aşamalı olarak kaldırılması için ise deprecation yöntemini kullanın.

Kullanımdan kaldırılan API sürümlerini ne kadar süreyle tutmalıyım?

Halka açık API'ler için, kullanımdan kaldırılan sürümleri en az 12-18 ay boyunca destekleyin. Dahili API'ler için, bir geçiş takvimi oluşturmak üzere istemci ekipleriyle koordinasyon sağlayın. Kullanımdan kaldırılan uç noktaları kaldırmadan önce her zaman önceden bildirimde bulunun (en az 3-6 ay). Kapatma işleminden önce istemcilerin geçiş yaptığından emin olmak için kullanım metriklerini izleyin.

Yanıt alanı sırasını değiştirebilir miyim?

Evet, JSON nesne alanının sırası API sözleşmesinin (contract) bir parçası değildir. İyi yazılmış istemciler JSON'ı konuma göre değil, alan adına göre ayrıştırır (parse eder). Ancak kötü yazılmış bazı istemciler alan sırasına bağımlı olabileceğinden kapsamlı testler yapın. Diziler (arrays) için sıra genellikle önemlidir ve belgelenmediği sürece değiştirilmemelidir.

URL yolu değişiklikleri yapmadan API'leri nasıl sürümlendirebilirim?

HTTP başlıklarını (headers) kullanın: Accept: application/vnd.myapi.v2+json veya API-Version: 2 gibi özel başlıklar. Sorgu parametreleri de işe yarar: /api/users?version=2. Başlıklar aracılığıyla içerik müzakeresi daha temizdir ancak tarayıcılarda test edilmesi daha zordur. Bir strateji seçin ve bunu tutarlı bir şekilde uygulayın.

Şimdi güvenliğinizi sağlayın

Kodunuzu, bulutunuzu ve çalışma zamanınızı tek bir merkezi sistemde güvenceye alın.
Güvenlik açıklarını otomatik olarak hızla bulun ve düzeltin.

Kredi kartı gerekmez | Tarama sonuçları 32 saniyede.