1 puan yazan GN⁺ 4 시간 전 | 1 yorum | WhatsApp'ta paylaş
  • Herkese açık bir web API’si Product API gibi bir adla birlikte /api/v1 yolunu kullanıyorsa, API’nin kendi semantik sürümü ile yapısı arasında uyumsuzluk oluşabilir
  • /v1/ yolu ile major.minor.patch kullanımını birlikte sürdürmek, route yapısıyla API sözleşmesini birbirine karıştırır ve semantik sürümün ilk sayısını URL’ye sabitler
  • Geriye dönük uyumluluğu bozan değişiklikler için yeni bir yol ve reverse proxy yönlendirmeleri gerekebilir; bu da sözleşme bilgisinin URL ile sürüm numarasına dağılmasına yol açabilir
  • Sonraki API aynı anda oluşturulursa mevcut API fiilen v1’e bağlanmış olur ve sonrasında uyumluluğu bozan değişikliklerde ad ile yolun anlamı belirsizleşir
  • Bu, herkese açık web API’lerinde tekrar tekrar rahatsız edici hale gelen sürümlendirme yaklaşımını sorgulayıp daha iyi tasarım ilkeleri arayan bir problem farkındalığıdır

1 yorum

 
GN⁺ 4 시간 전
Lobste.rs görüşleri
  • URL’de /v1/ bulundurmanın aslında büyük avantajlarından biri var. Uç noktayı kapatana kadar kullanıcıların API’yi bozacak değişikliklerle karşılaşmamasını zorunlu kılıyor

  • Aynı yazarın Evolving HTTP APIs gibi diğer yazıları da faydalı tavsiyeler veriyor

  • Temel olarak her route’a /v1/, /v2/ gibi ekleyerek geriye dönük uyumluluğu bozan değişiklikleri işaretliyorum. Birden fazla host üzerinde çalışan bir standardı tanımlamaya çalışmıyor, herkese açık çalışan bir API işletiyorsanız tam anlamıyla semantic versioning yapmanız için çok fazla neden yok
    Semantic versioning, esasen diğer geliştiricilerin değişiklik günlüğünü 20 dakika okumadan bağımlılıklarını güvenle yükseltebilmesi için var; çalışan bir API’de ise insanlar yeni bir minor sürümü ya da bugfix sürümünü ne zaman alacaklarını seçemez
    Neyin uyumluluğu bozan değişiklik sayılacağına gelince, belgelenmiş davranışı değiştiriyorsa ya da belgelenmiş davranışa dayanan mevcut istemcileri bozuyorsa bunu böyle değerlendiriyorum. Belgelenmemiş davranıştaki değişiklikleri de bozucu sayan yerler var ama bunun ciddi riskleri var

  • Google bunu şöyle yapıyor: AIP-185: API Versioning, AIP-180: Bacwards compatibility
    Bu tasarım belgeleri bana Google’ın çalışma biçimine oldukça özelmiş gibi geliyor ama API tasarlarken bunlara başvurdum ve içlerindeki bazı fikirler oldukça faydalıydı

  • Genel olarak tüm API’lerin geriye dönük uyumluluğu bozan değişiklikleri mümkün olduğunca azaltmaya çalışması gerektiğini düşünüyorum. Örneğin bir özelliğin adını değiştirmek istiyorsanız eski özelliği kaldırmak yerine yeni adı ona ek olarak sunmak daha iyi
    Ama Buttondown ekibinin yaptığı yöntem de temiz görünüyor. API sürümleri arasında migration tanımlıyorsunuz; böylece tüketici kendi API sürümünü bir header ile sabitleyebiliyor, sağlayıcı da değişiklik yapmaya devam edebiliyor

    • Çıktı özelliklerinde özelliği iki adla sunmak oldukça iyi işledi. Ancak girdi tarafında istemcinin iki özelliği farklı değerlerle göndermesi durumunu ele almanız gerekiyor
      “Yeni ad her zaman öncelikli olsun” cevabı akla geliyor ama istemci bir oku-değiştir-yaz akışı yürütüp sunucunun oluşturduğu nesnenin değiştirilmiş kopyasını geri gönderiyorsa bu bozulabilir. Çünkü istemci eski özelliği güncelleyip yeni özelliği yok sayarak aynen geri yollayabilir
    • API sağlayıcısının anlattığı gibi API sürümleri arasında migration sunmak iyi görünüyor ama sürümleme için HTTP istek header’ı kullanmak sorunlara yol açabilir
    • O bağlantı, veri biçimini nasıl ele alacağınızı çok iyi anlatıyor. Ama bu işin sadece bir kısmı; davranışın kendisi değiştiğinde ne yapılacağı da merak konusu
      Belki bu tür dönüşümler davranış eşlemesine de uygulanabilir ama gözümden kaçmadıysa o kısım ele alınmıyordu
  • İdeal olarak sürümü path’e koymalı ve yeni sürümleri eklemeli bir yapıda tasarlamalısınız. Böylece eski sürüm API, gerekli girdi/çıktı dönüşümlerini yapıp isteği daha yeni API sürümüne yeniden yönlendirebilir
    Birkaç yıl sonra artık kimse çok eski bir sürümü kullanmıyorsa onu kaldırabilirsiniz ve /v1/ yolu hata vermeye başlar

  • Bir zamanlar Accept header üzerinden content negotiation ile API sürümleme yapma yaklaşımını biraz okumuştum. Bunu gerçekten uygulayan biri varsa deneyimini duymak isterim
    Benim deneyimimde kaynak bazlı sürümleme ya da global sürümleme en sezgisel yaklaşımlardı. Kullanımdan kaldırma için Deprecation HTTP yanıt header’ını (RFC 9745) kullanıp, sonunda eski uç noktalarda 410 Gone gibi bir yanıt döndürmek, istemcileri yeni sürüme geçmeye yönlendirmek için makul bir yöntem gibi görünüyor
    Ayrıca birinin gerçekten evrilebilir bir API yapıp yapmadığını da merak ediyorum. Yani eski sürüm isteklerini içeride yeni API sürüm isteklerine çeviren, sonra da istemciler geçtikten ya da yeterli zaman geçtikten sonra eski sürümü gerçekten kaldıran bir yaklaşım