Yüksek Trafikli API Tasarımı: Sayfalama, Idempotency, Sürüm
Yüksek trafikli API tasarımı: cursor tabanlı sayfalama, idempotency anahtarları, sürümleme stratejisi, sözleşme-önce yaklaşım, HTTP önbellek başlıkları ve toplu uç noktalar.
Yüksek trafikli API'yi sıradan API'den ne ayırır?
Sıradan API doğru cevap verir; yüksek trafikli API doğru cevabı öngörülebilir maliyetle, tekrarlanan çağrılara dayanıklı ve yıllarca evrilebilir biçimde verir. Fark üç sözleşmededir: sayfalama sözleşmesi (maliyet), idempotency sözleşmesi (tekrar güvenliği) ve sürüm sözleşmesi (evrim). Bu yazı üçünü de üretim standardında kurar.
Sayfalama: offset'in gizli faturası
Offset sayfalama (page=500&size=20) küçük veride masumdur; büyük tabloda ise her sayfa, atlanacak satırların da taranması demektir — sayfa derinleştikçe sorgu maliyeti büyür ve araya giren yazmalar kayıt kaydırıp çift/eksik gösterir. Yüksek trafik standardı cursor (keyset) sayfalamadır: istemciye opak bir imleç verilir (son kaydın sıralama anahtarı kodlanmış halde), sonraki sayfa 'bu anahtardan sonrası' olarak indeksle çekilir — maliyet sayfa derinliğinden bağımsız sabitlenir, kayma sorunu kaybolur. Kurallar: imleç opak ve imzalı/kodlanmış olmalı (istemci içini kurcalamamalı), sıralama anahtarı tekil olmalı (created_at + id), ve toplam sayı ihtiyacı ayrı, önbelleklenebilir bir uca alınmalıdır — 'her sayfada COUNT(*)' klasik bir kendini-vurma desenidir.
Idempotency anahtarı: tekrar eden dünyada tekil etki
Önceki yazılarımızın kuralı burada API sözleşmesine döner: ağ, retry'lı istemciler ve çift tıklamalar aynı isteği birden çok kez getirir. Yazma uçları için desen nettir: istemci Idempotency-Key başlığı üretir (UUID); sunucu anahtarı ilk işleyişte sonuçla birlikte saklar (TTL'li); aynı anahtar tekrar geldiğinde işlem yeniden çalıştırılmaz, saklanan sonuç döner; işlenmekte olan anahtara eşzamanlı ikinci istek ise çakışma (409/425) alır. Ödeme, sipariş ve her 'çift etkisi para eden' uç için bu, tercih değil zorunluluktur. İnce nokta: anahtar + istek gövdesi birlikte doğrulanır — aynı anahtarla farklı gövde gelirse hata dönülür, sessiz kabul edilmez.
Sürümleme: kırmadan evrilmek
Yaklaşım | Örnek | Artı | Eksi |
|---|---|---|---|
URL sürümü | /v1/orders | Görünür, yönlendirmesi kolay | Kaba taneli; her değişiklik 'yeni dünya' |
Başlık sürümü | Accept: ...;v=2 | URL sabit; ince taneli | Görünürlük düşük; araç desteği ister |
Ekleyerek evrim | Yeni alanlar, eski alanlar korunur | Çoğu değişiklik sürümsüz geçer | Disiplin ve tolerant reader ister |
Pratik reçete karmadır: ana hat 'ekleyerek evrim' (alan eklemek serbest; silme/anlam değiştirme yasak) + kaçınılmaz kırıcı değişiklikler için URL sürümü. İki taraf da kurala bağlanır: sunucu bilinmeyen alan göndermekte özgürdür, istemci bilinmeyeni yok sayar (tolerant reader). Kullanımdan kaldırma da sözleşmedir: Deprecation/Sunset başlıkları, kullanım metriği ve takvimli kapatma — 'v1 hâlâ kimde?' sorusunun cevabı panoda olmalıdır.
Sözleşme-önce: OpenAPI üretim hattı
Yüksek trafikli API'de sözleşme, koddan türeyen dökümantasyon değil; kodun türediği kaynaktır: OpenAPI tanımı önce yazılır, sunucu iskeleti ve istemci SDK'ları (TypeScript tipleri dahil) bu tanımdan üretilir, CI'da örnek istek/cevap doğrulaması koşar. Kazanç zinciri nettir: frontend-backend paralel çalışır, kırıcı değişiklik CI'da yakalanır (şema diff), ve dış tüketicilere verilen SDK'lar elle yazılmaz. BFF yazımızdaki ekran sözleşmesi disiplininin genel API karşılığı budur.
Maliyet düşüren detaylar: önbellek başlıkları ve toplu uçlar
HTTP'nin yerleşik araçları yüksek trafikte ciddi para eder: değişmeyen kaynaklarda ETag/If-None-Match ile 304 cevabı gövde maliyetini sıfırlar; katalog benzeri içerikte Cache-Control CDN emilimini besler (önbellek yazımızdaki katman haritasına bağlanır). İkinci kalem N+1 çağrı deseninin API karşılığıdır: istemci 50 ürün için 50 çağrı yapıyorsa suç istemcide değil sözleşmededir — toplu uçlar (ids=1,2,3 ile çoklu okuma, toplu yazma uçları) ve alan seçimi (fields=id,name,price) çağrı sayısını ve gövde boyutunu birlikte düşürür. Hız limiti başlıkları (X-RateLimit-*, Retry-After) ise rate limiting yazımızdaki sözleşmenin istemciye görünen yüzüdür.
İş etkisi: API sözleşmesi bir kapasite ve gelir aracıdır
Cursor sayfalama + ETag + toplu uçlar, aynı işlevi belirgin ölçüde az veritabanı yükü ve bant genişliğiyle sunar — bu doğrudan altyapı faturasıdır. Idempotency, çift tahsilat/çift sipariş vakalarını ve onların müşteri hizmetleri maliyetini yok eder. Sürüm disiplini ise dış entegrasyonların (pazaryerleri, iş ortakları) güvenle bağlanmasını sağlar — API'niz bir ürünse, sözleşme kaliteniz satış argümanınızdır.
Sık sorulan sorular
GraphQL bu problemleri çözmez mi?
Bir kısmını başka maliyetle taşır: alan seçimi yerleşiktir ama sorgu maliyet kontrolü, N+1 çözümleyiciler ve önbellekleme sizin probleminiz olur. REST + iyi sözleşme, çoğu kurumsal senaryoda daha öngörülebilirdir.
Idempotency anahtarlarını ne kadar saklamalıyım?
İstemcinin gerçekçi retry penceresi kadar + pay: pratikte 24-72 saat yaygındır. Saklama TTL'i, sözleşmede açıkça belirtilmelidir.
Cursor sayfalamada 'sayfa 7'ye atla' nasıl yapılır?
Yapılmaz — bu offset'in işidir ve maliyeti onunla gelir. Doğru soru genelde 'atlama' değil filtre/aramadır; gerçekten sayfa numarası gereken (nadir) ekranlarda sınırlı derinlikte offset kabul edilebilir.
İç API'lerde de bu disiplin şart mı?
Trafik ve ekip sayısı büyüdükçe evet: iç tüketici de retry yapar, iç sözleşme de kırılır. En azından idempotency + tolerant reader + şema diff CI'ı iç hatlarda da standart olmalıdır.
API tasarım kontrol listesi
Liste uçları cursor sayfalamalı; imleç opak, sıralama anahtarı tekil
Tüm kritik yazma uçları Idempotency-Key destekli
Evrim kuralı yazılı: ekle serbest, kır → sürüm; tolerant reader zorunlu
OpenAPI kaynak; SDK/tipler üretiliyor; şema diff CI'da
ETag/Cache-Control stratejisi uç bazında tanımlı
Toplu uçlar ve alan seçimi ile çağrı/gövde diyeti uygulanıyor
Deprecation/Sunset süreci ve sürüm kullanım panosu mevcut
SSH Yazılım, yüksek trafikli API'lerin sözleşme tasarımını ve OpenAPI üretim hattını uçtan uca kurar. API'nizi ölçeğe birlikte hazırlayalım.