REST API Entegrasyonunda En Sık Görülen 7 Hata ve Çözümü
Zaman aşımı, mükerrer kayıt, rate limit ve doğrulanmamış webhook'lar: canlıda çalışan e-ticaret–ERP bağlantılarının sessizce bozulduğu yedi nokta ve her biri için uygulanabilir mühendislik deseni.
Sipariş e-ticaret panelinde duruyor, ERP'de yok. Ertesi hafta başka bir sipariş ERP'ye iki kez düşmüş, ikisine de fatura kesilmiş. Kimse kod değiştirmedi, sunucu da çökmedi. Bir REST API entegrasyonu genelde böyle bozulur; tamamen durarak değil, günde birkaç kaydı sessizce kaçırarak. Hata mesajı ya hiç loglanmamıştır ya da loglandığı dosyayı kimse açmıyordur.
Aşağıdaki yedi başlık, canlıdaki e-ticaret–ERP bağlantılarında en sık karşımıza çıkanlar. Hiçbiri egzotik değil; hepsi ilk gün kurulmadığı için sonradan operasyona fatura ediliyor.
Sahada teşhis belirtiden başlar. İşletme "sipariş kaçıyor" der; neden şunlardan biridir.
| Belirti | Çoğunlukla arkasındaki neden | Çözüm deseni |
|---|---|---|
| Gece senkronu bazı sabahlar yarım kalıyor | Zaman aşımı yok ya da çok uzun | Ayrı bağlantı/okuma süresi + üstel artan bekleme |
| Aynı sipariş iki kez düşüyor | Yeniden deneme var, tekilleştirme yok | Idempotency key ve benzersiz indeks |
| Kampanya günü istekler reddediliyor | İstek kotası aşımı, 429 yanıtı yok sayılıyor | Kuyruk, eşzamanlılık sınırı, Retry-After |
| Bazı siparişler hiç gelmiyor | Yalnızca webhook'a güvenilmiş | Webhook + periyodik fark taraması |
| Kaynağı belirsiz kayıtlar oluşuyor | İmza doğrulanmıyor, tekrar gönderim işleniyor | HMAC doğrulama + olay kimliğiyle tekilleştirme |
| Toplu çekim 504 ile ölüyor | Sayfalama yok, tek istekte her şey isteniyor | Cursor tabanlı sayfalama, parçalı işleme |
| Hata olduğu haftalar sonra anlaşılıyor | Başarısız kayıt hiçbir yere yazılmıyor | Dead letter kuyruğu ve eşikli alarm |
1. Zaman aşımı tanımlamamak, yeniden denemeyi körlemesine kurmak
En sık görülen API timeout hatası karşı tarafın yavaşlığından değil, istemcinin sabır sınırı olmamasından doğar. Varsayılan ayarla bırakılan bir HTTP istemcisi dakikalarca bekler; bu sırada cron bir sonraki turu başlatır ve iki iş aynı veriyi işlemeye kalkar. Bağlantı süresi ile okuma süresini ayrı tanımlayın: bağlantı için birkaç saniye yeter, okuma süresi isteğin ağırlığına göre değişir. Turların üst üste binmesini ise zaman aşımı değil, zamanlanmış işin üzerine konan bir çalışma kilidi engeller.
Üstel artan bekleme ve rastgele sapma
Hata alan isteği hemen tekrar göndermek karşı sistemi daha da zorlar. Beklemeyi katlayarak artırın: 1 saniye, 2, 4, 8. Üstüne küçük bir rastgele sapma ekleyin; yoksa hata anında düşen kırk işçi aynı saniyede uyanır, karşı taraf ikinci dalgada da cevap veremez. Deneme sayısına da bir tavan koyun; sonsuza kadar denenen istek, hatayı çözmez, sadece geciktirir.
Her hata tekrar denenmez
Denemeyi hata tipine bağlamadan yazmak, sorunu gidermek yerine kalıcı hale getirir. Vergi numarası hatalı olduğu için 422 dönen bir isteği yüz kez göndermek, yüz kez aynı cevabı alır; kotayı da o sırada bitirir.
| Yanıt | Tipik anlamı | Tekrar denenir mi? |
|---|---|---|
| Bağlantı hatası / zaman aşımı | Ağ ya da karşı taraf geçici olarak erişilemiyor | Evet, artan beklemeyle |
| 500, 502, 503, 504 | Sunucu tarafı geçici arıza | Evet, sınırlı sayıda |
| 429 | İstek kotası doldu | Evet, ama Retry-After süresine uyarak |
| 400, 422 | Gönderilen veri geçersiz | Hayır, veri düzeltilmeden anlamsız |
| 401 | Kimlik doğrulanamadı, token süresi dolmuş olabilir | Bir kez, token yenilendikten sonra |
| 403 | Kimlik doğru, bu işlem için yetki yok | Hayır, yetki tanımı düzeltilmeden anlamsız |
| 404 | Kayıt karşı tarafta yok | Hayır, eşleştirme sorunudur |
2. Idempotency key olmadan yeniden deneme yapmak
Idempotency key, aynı isteğin karşı tarafa kaç kez ulaştığından bağımsız olarak tek bir kayıt oluşmasını sağlayan benzersiz işlem etiketidir. Neden gerektiği şu senaryoda görünür. İstek ulaştı, sipariş yazıldı, ama yanıt dönerken bağlantı koptu. Sizde görünen şey bir zaman aşımı; istek tekrarlanır, ikinci sipariş oluşur. Aynı senaryo faturada ve stok hareketinde de geçerli.
Yeniden deneme kurup idempotency uygulamamak, hatayı çözmez; ikiye katlar. Bu iki şey ayrı ayrı değil, hep birlikte devreye alınır.
Asıl mesele anahtarın denemeler arasında değişmemesi. Her denemede yeni rastgele değer üretilirse işlevi kalmaz; kaynak sistemin sipariş numarasıyla işlem tipini birleştirmek çoğu senaryoda yeterli. Anahtarın karşı tarafta ne kadar süre hatırlandığını da sorun; koruma o pencere kadar sürüyor, ötesinde aynı anahtar yeni kayıt açıyor. Karşı taraf idempotency başlığını desteklemiyorsa koruma sizde kurulur: dış belge numarasını iç belge numarasına bağlayan bir eşleme tablosu ve veritabanı seviyesinde benzersiz indeks. "Önce sorgula, yoksa yaz" kontrolü tek başına yetmez; iki işçi aynı anda sorgularsa ikisi de "yok" cevabını alır. Bu katmanı özel yazılım tarafında baştan kurmak, sonradan mükerrer kayıt temizlemekten ucuza gelir.
3. Rate limit aşımını hata sanmak
429 bir arıza değil, "yavaşla" mesajıdır. Onu genel hata sayıp hemen tekrar denemek kotayı daha da doldurur, bazı sağlayıcılarda bekleme süresini uzatır. Doğrusu yanıtın başlıklarını okumak: Retry-After varsa süre bellidir, kalan kota veriliyorsa isteklerinizi ona göre yayarsınız.
API rate limit aşımı normal günlerde değil, kampanya günlerinde ortaya çıkar. Ayda 12.000 sipariş işleyen bir mağaza kasım kampanyasında tek günde 3.000 sipariş alır; aynı kod aynı hızla çalışmaya devam eder ve duvara toslar. Kurgu şöyle olmalı:
- İstekler kuyruk üzerinden gitsin. Kuyruk, ani yükü zamana yayan tek yapıdır.
- Eşzamanlı işçi sayısını sınırlayın. On işçiyi kırka çıkarmak, kotası dakikada 60 istek olan bir uçta hiçbir şey hızlandırmaz.
- Kotayı uç bazında ölçün. Ürün güncelleme ile sipariş okuma genelde ayrı sınırlara tabidir.
- Toplu uçları tercih edin. 500 ürünü paket halinde kabul eden bir uç varsa kota sorununun yarısı çözülür.
4. Her veri tipi için aynı yöntemi kullanmak
Webhook mu polling mi sorusunun tek cevabı yok; veri tipine göre değişir. Webhook anlıktır ama garanti değildir. Sağlayıcıların çoğu ulaşmayan bildirimi bir süre tekrar dener; o pencere kapandıktan sonra olay bir daha gelmez. Pencerenin uzunluğu sağlayıcıya göre saatlerle günler arasında değişiyor, kesintiniz onu aşarsa kayıp kalıcı oluyor. Zamanlanmış sorgulama gecikmelidir, buna karşılık kaçırdığını sonraki turda toplar.
| Veri tipi | Uygun yöntem | Gerekçe |
|---|---|---|
| Yeni sipariş | Webhook + günlük fark taraması | Gecikme tolere edilmez, kayıp hiç edilmez |
| Sipariş durum değişikliği | Webhook | Olay anında tetiklenir, hacmi düşüktür |
| Stok ve fiyat güncellemesi | Planlı toplu iş | Yüksek hacim, paket halinde daha verimli |
| Kargo takip durumu | Zamanlanmış sorgulama | Her taşıyıcıda olay bildirimi bulunmaz |
| Ürün ve kategori ana verisi | Gece toplu aktarım | Nadiren değişir, anlık olması gerekmez |
| Fatura ve cari mutabakatı | Günlük sorgulama + fark raporu | Doğruluk hızdan önce gelir |
Çoğu projede atlanan şey ilk satırdaki "fark taraması". Webhook kurulur, iş bitti sanılır. Oysa son 24 saatin siparişlerini listeleyip kendi veritabanınızla karşılaştıran günlük bir görev, kaçan kaydı aynı gün yakalar. Stok ve sipariş akışının ERP tarafındaki karşılığını Nebim V3 – e-ticaret entegrasyonu yazısında anlatmıştık; kanal tarafındaki kapsam ise e-ticaret entegrasyonları sayfasında.
5. Gelen webhook isteğine doğrulamadan güvenmek
Webhook ucunuz internete açık bir kapıdır. İmza doğrulaması yoksa o adrese istek atan herkes sisteminize sipariş yazdırabilir. Sağlayıcıların çoğu paylaşılan gizli anahtarla üretilmiş bir imza başlığı gönderir. Püf nokta şu: imza ham gövde üzerinden hesaplanır. JSON'u ayrıştırıp yeniden birleştirirseniz imza tutmaz. Karşılaştırmayı da düz eşitlik yerine sabit zamanlı bir fonksiyonla yapın. Yanına zaman damgası kontrolü koyun: birkaç dakikadan eski bir isteği reddetmek, kaydedilmiş bir çağrının sonradan tekrar oynatılabileceği pencereyi birkaç dakikaya indirir. O pencerenin içini kapatan şey aşağıdaki olay kimliği kontrolü; ikisi birlikte çalışır.
İkinci konu tekrar gönderimler. Sağlayıcı hızlı bir 200 alamazsa isteği başarısız sayar ve tekrarlar; aynı olayın üç dört kez gelmesi normaldir. Webhook mükerrer kayıt sorununun kaynağı budur. Çözüm iki parçalı: her olayın kimliğini işlenmiş olaylar tablosuna yazıp aynısı geldiğinde sessizce 200 dönmek, bir de webhook ucunda ağır iş yapmamak. İsteği kuyruğa atın, ERP'ye yazma arka planda yürüsün.
Olaylar geldiği sırayla üretilmemiş olabilir
Aynı siparişin "hazırlanıyor" ve "kargolandı" bildirimleri ters sırada düşebilir; tekrar denenen bir bildirim, kendisinden sonra üretilmiş olanın arkasından gelir. Gelen veriyi koşulsuz yazarsanız sipariş ekranda geri gider, müşteriye yanlış bilgi çıkar. Her olayın sürüm ya da oluşma zamanı alanını saklayın, yalnızca elinizdekinden yeni olanı uygulayın. Kapanmış bir kaydı geri açacak durum geçişini de kabul etmeyin; böyle bir olay hata kuyruğuna düşsün.
6. Toplu veri çekerken sayfalamayı ve parçalı işlemeyi atlamak
"Tüm siparişleri çek" isteği ilk aylarda çalışır. Veri büyüdükçe aynı istek 504 ile döner ya da bellek sınırına çarpar. İki yöntem var: offset ve cursor tabanlı sayfalama. Offset basittir ama siz 30. sayfayı okurken araya yeni kayıt girerse bazı satırlar atlanır, bazıları iki kez gelir. Cursor tabanlı ilerlemek bu riski büyük ölçüde kaldırır. Tarih aralığıyla ilerlemek de iş görür, ama kendi tuzağı var: sınıra denk gelen aynı saniyedeki kayıtlar bölünür. Aralığı birkaç dakika geriye bindirin, tekrar gelen kayıtları kimliğine bakıp eleyin.
Yazma yönünde de aynı mantık geçerli. 50.000 satırlık bir stok güncellemesini tek istekte göndermek yerine 500'lük paketlere bölün, her paketin sonucunu ayrı kaydedin. Bir paket düşerse diğerleri etkilenmez. Son işlenen kaydın zaman damgasını saklayın; sunucu yeniden başladığında iş kaldığı yerden devam eder. Bu damganın hangi saat diliminde tutulduğunu bir kez netleştirin. Sunucu UTC, karşı sistem yerel saat çalışıyorsa fark sorgusu üç saatlik bir pencereyi sessizce atlar.
7. Başarısız kaydın gideceği bir yer olmaması
Bir istek üç deneme sonunda da başarısızsa ne oluyor? Çoğu projede cevap "hiçbir şey". Kayıt kaybolur, kimse bakmaz. Hata kuyruğu (dead letter) bu boşluğu doldurur. Ayrımı baştan yapın: hangi hata kendi kendine düzelir, hangisi insan müdahalesi ister.
- Kendi kendine düzelenler: ağ kopması, zaman aşımı, 5xx ve kota aşımı. Artan beklemeyle yeniden denenir, operasyonu rahatsız etmez.
- Veri düzeltmesi isteyenler: zorunlu alanı boş sipariş, geçersiz vergi numarası, karşı tarafta karşılığı olmayan ürün kodu. Yeniden deneme bunları çözmez.
- Yetki ve yapılandırma hataları: süresi dolmuş token, kapatılmış uç, değişmiş adres. Tek tek değil toplu patlar; ilk birkaç hatada alarm üretmeli.
- İş kuralı reddi: stok yetersiz, kredi limiti aşıldı, sipariş kapalı. Yazılım hatası değil; operasyonun karar vermesi gerekir.
Dead letter kaydında ham istek, dönen yanıt, deneme sayısı, son hata mesajı ve belge numarası birlikte dursun. Panelden tek tuşla yeniden gönderme olsun; düzeltilen kaydın akması geliştirici işi olmaktan çıkar. Alarmda eşik kullanın. Her hataya e-posta atan bir sistem üç günde filtreye düşer; "son 15 dakikada 20'den fazla başarısız kayıt" gibi bir kural gerçek arızayı öne çıkarır. Bu kontrolleri ve kuyruk altyapısını süreç otomasyonu tarafında kuruyoruz.
Loglama, ortam farkları ve kayıt saklama
API entegrasyonu nasıl yapılır sorusunun en az konuşulan kısmı şu: sorun çıktığında elinizde ne olacak? Her istek ve yanıt için bir korelasyon kimliği üretin. Bir siparişin panele düşmesinden faturasının kesilmesine kadar tüm adımları aynı kimlikle izlemek, hata arama süresini saatlerden dakikalara indirir. Yanıt süresi, durum kodu ve deneme sayısı aynı satırda dursun. Gövdeyi loglarken maskeleyin; token, kart ve kimlik bilgisi düz metin durmamalı. Saklama süresi duruma göre değişir: mutabakat pencerenizi karşılayacak kadar tutup ötesini özetlemek makul bir denge. Kişisel veri içeren alanlarda süreyi ayrıca kısa tutun.
Test ile canlı arasındaki farkları da baştan yazın. Sağlayıcıların test ortamlarında kota sınırı ya yoktur ya çok gevşektir; canlıda ilk kampanya gününde tanışırsınız. Veri hacmi de küçüktür, sayfalama hataları orada görünmez. Ayrı anahtar, ayrı veritabanı, ayrı kuyruk adı kullanın. Test ortamının canlıya sipariş yazdığı durumlar sanıldığından daha sık yaşanıyor; fark edilmesi de genelde bir müşteri şikâyetiyle oluyor.
Bu konuda nasıl yardımcı oluyoruz?
Yuog Dev olarak e-ticaret işletmelerinin ERP, entegrasyon ve otomasyon altyapısını kuruyoruz. İhtiyaç analiziyle başlıyor, ölçülebilir hedefler koyuyor ve teslim sonrasında da destek veriyoruz. Süreçlerinizi konuşmak isterseniz iletişim sayfasından bize ulaşabilirsiniz.