- Yazılım mühendisliğinde API’ler temel araçlardır ve iyi bir API’nin sıkıcı derecede tanıdık ve basit olması arzu edilen bir özelliktir
- Bir API bir kez yayımlandıktan sonra değiştirilmesi zor olduğundan, kullanıcı alanını bozmama ilkesi (WE DO NOT BREAK USERSPACE) önemlidir
- Değişiklik kaçınılmaz olduğunda sürümleme (versioning) gerekir, ancak bu karmaşıklığı ve bakım maliyetini ciddi biçimde artıran gerekli bir kötülüktür
- API kalitesi sonuçta ürünün kendi değerine bağlıdır; kötü tasarlanmış bir ürün iyi bir API oluşturmayı zorlaştırır
- Kararlılık ve ölçeklenebilirlik için API anahtarı tabanlı kimlik doğrulama, idempotency, rate limiting, cursor tabanlı sayfalama gibi unsurlar dikkate alınmalıdır
Giriş: API tasarımının önemi ve bağlamı
- Modern yazılım mühendislerinin temel işlerinden biri API’lerle etkileşime girmektir
- Yazar da REST, GraphQL, komut satırı araçları gibi çeşitli biçimlerde genel kullanıma açık ve kurum içi API’ler tasarlama/uygulama/kullanma deneyimine sahiptir
- Mevcut API tasarımı tavsiyeleri, karmaşık kavramlara (REST’in tanımı, HATEOAS vb.) takılma eğilimindedir
- Bu yazı, gerçek deneyime dayanarak pratik API tasarım ilkelerini derler
Tanıdıklık ile esneklik dengesi: iyi API’nin ilk koşulu
- İyi API, “sıradan ve sıkıcı” bir API’dir; yani daha önce kullanılan API’lerle benzer şekilde çalışmalıdır
- Kullanıcılar API’nin kendisinden çok kendi hedeflerine ulaşmaya odaklandığı için, giriş eşiği düşük bir tasarım gerekir
- Bir kez yayımlanan API’yi değiştirmek çok zordur, bu yüzden ilk tasarım aşamasında dikkatli olunmalıdır
- Geliştiriciler mümkün olduğunca sade bir API isterken, uzun vadeli esneklik bırakma ihtiyacı da her zaman vardır
- Sonuç olarak temel mesele, tanıdıklık ile uzun vadeli esneklik arasındaki dengeyi kurmaktır
Kullanıcı alanını asla bozma (WE DO NOT BREAK USERSPACE)
- Mevcut yanıt yapısına alan eklemek çoğu durumda sorun yaratmaz
- Ancak alan kaldırma, tür veya yapı değiştirme tüm tüketici kodunu bozacak sonuçlar doğurur
- API’yi sürdürenlerin, mevcut kullanıcıların yazılımlarını bilerek bozmama sorumluluğu vardır
- HTTP’deki
referer başlığındaki yazım hatasının bile düzeltilmemesinin nedeni, kullanıcı alanını koruma kültürüdür
API’yi bozmadan değiştirmek: sürümleme stratejisi
- Yıkıcı değişiklikler API’de yalnızca zorunlu olduğunda yapılmalıdır; bu durumda doğru yaklaşım sürümlemedir
- Eski ve yeni sürüm aynı anda çalıştırılarak kademeli geçiş sağlanmalıdır
- Sürüm tanımlayıcısı URL (
/v1/), başlıklar ve başka yollarla verilebilir; kullanıcılar kendi hızlarında geçiş yapabilir
- Sürümlemenin muazzam bir bakım maliyeti (artan endpoint sayısı, test, destek) ve kullanıcı kafa karışıklığı gibi dezavantajları vardır
- Stripe gibi iç çeviri katmanları kullanılsa bile, temel karmaşıklıktan kaçınılamaz
- API sürümlemesine başvurmak son çare olmalıdır
API’nin başarısı tamamen ürün değerine bağlıdır
- API, özünde gerçek bir iş ürününün arayüzünden ibarettir
- OpenAI, Twilio gibi API’lerde de kullanıcıların asıl istediği şey, API’nin sunduğu işlevin kendisidir
- Değerli bir ürünse, API rahatsız edici olsa bile kullanılır
- API kalitesi bir tür “marj” özelliğidir: ancak temel rekabet gücü benzer olduğunda seçim kriteri olur
- Buna karşılık, hiç API’si olmayan bir ürün teknik kullanıcılar için büyük bir engeldir
Ürün tasarımı kötüyse API de iyi olamaz
- Teknik olarak çok iyi yapılmış bir API olsa bile, pazarda karşılığı olmayan bir ürün için bunun anlamı yoktur
- Daha da önemlisi, temel kaynak yapısı mantıksız ya da verimsizse bu API’de de görünür
- Örneğin yorumları linked list olarak saklayan bir sistemde RESTful bir tasarımı doğal biçimde kurmak bile zorlaşır
- UI’da gizlenebilen teknik sorunlar API’de doğrudan ortaya çıkar ve kullanıcıdan sistemi gereksiz yere derinlemesine anlamasını ister
Kimlik doğrulama (Authentication) ve kullanıcı çeşitliliği
- Uzun ömürlü API anahtarı tabanlı kimlik doğrulama mutlaka desteklenmelidir
- OAuth gibi daha güvenli yöntemler ek olarak desteklense bile, API anahtarlarının giriş eşiği çok daha düşüktür
- API tüketicileri yalnızca mühendislerden ibaret değildir; geliştirici olmayanlar da (satış, planlama, öğrenciler, hobi amaçlı geliştiriciler vb.) çoktur
- Zor veya karmaşık kimlik doğrulama gereksinimleri (OAuth vb.) uzman olmayan kullanıcılar için bir engel oluşturur
İdempotency ve yeniden deneme işlemleri
- Aksiyon içeren isteklerde (ör. ödeme, durum değişikliği vb.) hata durumunda yeniden deneme (retry) güvenliği önemlidir
- İdempotency, aynı isteğin birden fazla kez gönderilse bile sonucun yalnızca bir kez işlenmesini garanti etmek demektir
- Standart yöntem, tekrar işlemeyi önlemek için parametre veya başlıkta bir idempotency key iletmektir
- İdempotency key saklama için Redis gibi basit bir anahtar/değer deposu yeterlidir; çoğu durumda periyodik süre sonu uygulamakta sakınca yoktur
- Okuma/silme isteklerinde (REST tarzında) buna genellikle ihtiyaç yoktur
API güvenliği ve rate limiting
- Kod üzerinden yapılan API istekleri, kullanıcı etkileşiminden çok daha hızlı gerçekleşebilir
- Düşünmeden yayımlanan tek bir API bile beklenmedik bir amaçla (ör. büyük ölçekli sohbet sistemi) kullanılabilir
- Rate limiting mutlaka gereklidir ve maliyeti yüksek işlemlerde daha sıkı uygulanmalıdır
- Belirli bir müşteri için geçici API devre dışı bırakma (killswitch) seçeneği de düşünülmelidir
- Rate limit bilgisi yanıt başlıklarıyla (
X-Limit-Remaining, Retry-After vb.) açıkça bildirilmelidir
Sayfalama (Pagination) stratejisi
- Büyük veri kümelerini (ör. milyonlarca ticket) verimli döndürmek için sayfalama şarttır
- Offset tabanlı sayfalama basittir, ancak büyük veri üzerinde giderek yavaşlar
- Cursor tabanlı sayfalama, sorgu performansını düşürmeden çok büyük veri kümelerinde de etkilidir
- Cursor tabanlı yaklaşımın uygulanması ve kullanımı biraz daha zor olsa da, uzun vadede kaçınılmaz bir değişim olabilir
- Yanıta
next_page gibi alanlar ekleyerek bir sonraki isteğin cursor bilgisini açıkça göstermek akıllıcadır
İsteğe bağlı alanlar ve GraphQL hakkındaki görüş
- Maliyeti yüksek veya yavaş alanlar varsayılan yanıttan çıkarılmalı, yalnızca gerektiğinde isteğe bağlı olarak eklenmelidir
includes parametresi vb. ile ilişkili veriler dâhil edilebilir
- GraphQL veri yapısı esnekliği açısından avantaj sunsa da, geliştirici olmayanlar için erişilebilirliğin azalması, caching/edge case karmaşıklığı ve arka uç uygulama zorluğu gibi sorunları vardır
- Pratik deneyime göre GraphQL benimsemesi yalnızca gerçekten gerekli olduğunda uygundur
İç kullanım API’lerinin özellikleri
- Kurum içi API’ler, dışa açık API’lerden birçok açıdan farklıdır
- Tüketiciler çoğunlukla uzman yazılım mühendisleri olduğundan, daha karmaşık kimlik doğrulama ya da yıkıcı değişiklikler kabul edilebilir
- Yine de idempotency, hata önleme ve operasyonel yükü azaltma için tasarım ilkeleri geçerliliğini korur
Kısa özet
- API’leri değiştirmek zordur, kullanmak ise kolay olmalıdır
- Kullanıcı alanını bozmamak, API’yi sürdürenlerin en önemli yükümlülüğüdür
- API sürümlemesi yüksek maliyetli olduğundan yalnızca son çare olarak kullanılmalıdır
- Sonuçta API kalitesini belirleyen şey ürünün öz değeridir
- Kötü tasarlanmış bir ürünün eksikleri API düzeyinde giderilmeye çalışılsa bile bunun sınırları vardır
- Basit kimlik doğrulama desteği, gerekli aksiyon isteklerinde mutlaka idempotency, ayrıca rate limiting/sayfalama gibi kararlılık önlemleri önemlidir
- İç API’lerde strateji kullanım amacına ve hedef kitleye göre değişse de, dikkatli tasarım hâlâ gereklidir
- REST, JSON gibi formatlar veya OpenAPI gibi araçlar temel mesele değildir; önemli olan açık dokümantasyondur
Henüz yorum yok.