API Endpoint Nasıl Test Edilir: DNS, TLS, Başlık ve CORS

Önemli bilgi

"API çöktü" neredeyse hiçbir zaman tek bir sorun değildir. Altı katmanda test edin (DNS, 443 portu, TLS, HTTP durumu, CORS, payload) ve ilk başarısız olan katmanda durun. Tipik suçlular: hiç yayılmamış bir DNS kaydı, gece süresi dolan bir sertifika veya curl sorunsuz çalışırken tarayıcı çağrılarını bozan eksik bir Access-Control-Allow-Origin başlığı.

Şimdi kontrol edin

Herkese açık bir API endpoint'ini test etmenin altı katmanı: DNS çözümleme, 443 portu, TLS sertifikası, HTTP başlıkları, CORS ve JSON payload diyagramı
Herkese açık bir API endpoint'ini test etmenin altı katmanı: DNS çözümleme, 443 portu, TLS sertifikası, HTTP başlıkları, CORS ve JSON payload diyagramı
Okumaya başlayın
  1. "API çöktü" neden hiçbir zaman tek bir sorun değildir
  2. Rahatça deneyebileceğiniz gerçek bir endpoint seçin
  3. Katman 1: Ana bilgisayar adı çözümleniyor mu?
  4. Katman 2: 443 portu açık mı?
  5. Katman 3: TLS sertifikası geçerli mi?
  6. Katman 4: Yanıt başlıklarını okuyun
  7. Sağlıklı bir JSON yanıtı nasıl görünür
  8. Katman 5: Yalnızca tarayıcı çağrılarını bozan başlık
  9. Preflight tuzağı: Başlık ekleyene kadar çalışır
  10. Katman 6: Payload beklediğiniz biçimde mi?
  11. Belirti → katman → araç
  12. Sıkça Sorulan Sorular

"API çöktü" neden hiçbir zaman tek bir sorun değildir

Bir API çağrısı başarısız olduğunda, istemcinizin gösterdiği hata genellikle gerçekte bozulan şeyin birkaç katman üstünde üretilir. Failed to fetch bildiren bir tarayıcı, ana bilgisayar adının çözümlenmediğini, TCP bağlantısının reddedildiğini, TLS el sıkışmasının reddedildiğini ya da sunucunun gayet sağlıklı bir 200 döndürdüğünü ama tarayıcının eksik bir CORS başlığı yüzünden onu attığını söyleyemez. Dört durum da aynı mesajı üretir.

Çözüm tahmin etmeyi bırakıp yığını sırayla yürümektir. Her katman ancak altındaki başarılıysa anlamlıdır, bu yüzden başarısız olan ilk katman gerçek hatanızdır; sonrasındaki her şey gürültüdür.

Kontrol etmeye değer altı katman var ve hepsi birlikte yaklaşık iki dakika sürer:

  • DNS: ana bilgisayar adı bir IP'ye çözümleniyor mu?
  • 443 portu: dinleyen bir şey var mı, yoksa bağlantı reddediliyor veya filtreleniyor mu?
  • TLS: sertifika geçerli, süresi dolmamış ve tam zincirle mi sunuluyor?
  • HTTP durumu: sunucu gerçekte ne döndürüyor: 200, 401, 429, 503?
  • CORS: yanıt, tarayıcının gövdeyi size vermesi için gereken başlıkları taşıyor mu?
  • Payload: JSON, kodunuzun beklediği biçimde mi?

Bir endpoint'in durumunu ve başlıklarını şimdi kontrol edin

Rahatça deneyebileceğiniz gerçek bir endpoint seçin

Uygulamak için gerçek veri döndüren, API anahtarı gerektirmeyen ve aynı isteği yirmi kez çalıştırdığınız için sizi sınırlamayacak canlı bir endpoint gerekir. Bu, bariz adayların çoğunu eler: neredeyse her yaygın herkese açık API artık sizi bir kayıt formu ve bir token arkasına alıyor; yani başarısız bir istek, test ettiğiniz katman yerine hep kimlik bilgilerinizden kaynaklanıyor olabilir.

Aşağıdaki örnekler, 100'den fazla ülkede 60.000'den fazla yeri kapsayan Arapça bir namaz vakti servisi olan Waqt Azan (مواقيت الصلاة) sitesinin ücretsiz namaz vakti API'sini kullanır. Öğretici bir endpoint olarak üç nedenle iyi çalışır: anahtar ve kimlik doğrulama başlığı yoktur, HTML yerine yapılandırılmış JSON döndürür ve izin verici bir CORS politikası belirler. Böylece curl komutları olduğu gibi çalışır, fetch() örneği de katı bir Content-Security-Policy olmayan bir sayfanın konsolunda çalışır.

Endpoint, ülke ve şehir slug'ını doğrudan yolda alır:

bash
# Prayer times for a city — no API key, no headers required
curl -s https://waqtazan.com/api/v1/timings/saudi-arabia/riyadh

# The same data as a subscribable calendar feed
curl -s https://waqtazan.com/api/v1/ical/saudi-arabia/riyadh.ics

Gerçekten hata ayıkladığınız ana bilgisayarla değiştirin: ister herkese açık bir API, ister kendi staging sunucunuz, ister üçüncü taraf bir webhook alıcısı test edin, altı katman aynıdır.

Katman 1: Ana bilgisayar adı çözümleniyor mu?

DNS sık görülen bir suçludur. Bir kayıt değiştirildi ve yayılmadı, bir wildcard kaldırıldı ya da API hiç oluşturulmamış bir alt alan adında duruyor.

Her şeyden önce ana bilgisayar adını çözümleyin. Bu adım hiçbir şey döndürmüyorsa uygulamanızı yeniden başlatmak işe yaramaz: istemciniz bir soket açacak kadar bile ilerleyemez.

bash
dig +short waqtazan.com A
nslookup waqtazan.com

# Compare what different resolvers see — catches mid-propagation records
dig +short waqtazan.com A @1.1.1.1
dig +short waqtazan.com A @8.8.8.8

Bir kaydı değiştirdikten hemen sonra iki herkese açık çözümleyici birbirinden farklı yanıt veriyorsa kayıt hâlâ yayılıyordur ve API, her istemcinin hangi çözümleyiciye düştüğüne bağlı olarak aralıklı bozuk görünür (coğrafi yönlendirme yapan bir CDN her çözümleyiciye sürekli farklı bir adres verebilir, bu yüzden ayarladığınız kayıtla karşılaştırın). Tüm kayıt kümesini görmek için bir DNS sorgusu yapın ya da bir kaydı değiştirdikten hemen sonra küresel çözümleyicilerde yayılmayı DNS yayılma denetleyicisi ile kontrol edin.

Burada boş bir yanıt, Chrome'da doğrudan ERR_NAME_NOT_RESOLVED ve Node'da getaddrinfo ENOTFOUND hatasına karşılık gelir: tam çözüm listesi için ERR_NAME_NOT_RESOLVED yazısına bakın.

Endişelenmemeniz gereken bir şey: birçok API bir CDN'in arkasındadır, bu yüzden A kaydı kaynak sunucuyu değil bir CDN uç noktasını gösterir. Bu beklenen bir durumdur. Önemli olan hangi IP'nin geldiği değil, bir yanıt alıp almadığınızdır.

Katman 2: 443 portu açık mı?

Ana bilgisayar adı çözümleniyor, yani bir adres var. Şimdi üzerinde bir şeyin dinleyip dinlemediğini öğrenin. İstemcilerin aynı şekilde bildirmeyi sevdiği üç çok farklı arızayı burada ayırırsınız:

  • Açık: TCP el sıkışması tamamlanır. Sonraki katmana geçin.
  • Reddedildi: ana bilgisayar anında bir RST ile yanıt verdi. Orada bir şey var ama o porta bağlı hiçbir şey yok; genellikle servis çökmüştür veya yalnızca localhost'ta dinliyordur.
  • Filtreleniyor: bağlantı zaman aşımına kadar takılı kalır. Bir güvenlik duvarı ya da güvenlik grubu paketleri sessizce düşürür; isteğiniz bu yüzden başarısız olmadan önce bir dakika veya daha fazla bekler (macOS'ta 75 saniye).
bash
# Time-boxed TCP check: -w limits the connect on Linux; on macOS use -G 5 instead
nc -vz -w 5 waqtazan.com 443

# Or with curl: --connect-timeout caps the connect; 000 means no response came back
curl -s -o /dev/null -w '%{http_code}\n' --connect-timeout 5 https://waqtazan.com/

Reddedilen ve filtrelenen bir bağlantı tamamen farklı çözümler gerektirir, bu yüzden hangisine sahip olduğunuzu bilmek değerlidir. Port denetleyicisi ikisini ayırt eder ve ağınızın dışından test eder; bu önemlidir, çünkü ofis VPN'inizden açık görünen bir port, herkese açık internetten güvenlik duvarıyla kapalı olabilir.

curl durum kodu olarak 000 yazdırıyorsa hiçbir HTTP yanıtı gelmemiştir. Genellikle istek 1–3. katmanlarda başarısız olmuştur (DNS yanıtı yok, reddedilen veya filtrelenen port, başarısız TLS el sıkışması), ancak bağlantıyı kabul edip sonra kapatan ya da hiç yanıt vermeyen bir sunucu da 000 verir; çalışan son adımı görmek için -v ekleyin. Reddedilme durumunu ayrıntılı olarak ERR_CONNECTION_REFUSED yazısı anlatır.

Katman 3: TLS sertifikası geçerli mi?

443 portu açık ama açık bir port çalışan bir HTTPS endpoint'i demek değildir. Sertifikalar klasik bir gece arızasıdır, çünkü belirli bir tarihte sona erer ve yenileme otomasyonu sessizce başarısız olur.

Sertifikanın aynı anda üç şartı sağlaması gerekir: süresi dolmamış olmalı, adı istediğiniz ana bilgisayar adıyla eşleşmeli ve sunucu tam ara sertifika zincirini göndermeli. Üçüncüsü sinsi olandır: eksik bir zincir tarayıcılarda çoğu zaman çalışır, çünkü Chrome eksik ara sertifikayı kendisi indirir ve Firefox ara sertifikaları önceden yükler; oysa Node, Python, Java ve OpenSSL tabanlı curl derlemeleri başarısız olur (macOS ile gelen curl Apple'ın doğrulayıcısını kullanır ve geçebilir). Klasik "tarayıcımda çalışıyor ama production'da çalışmıyor" hata raporunun kaynağı budur.

bash
# Expiry dates and subject
echo | openssl s_client -connect waqtazan.com:443 -servername waqtazan.com 2>/dev/null \
  | openssl x509 -noout -subject -dates

# Full chain as presented by the server
openssl s_client -connect waqtazan.com:443 -servername waqtazan.com -showcerts < /dev/null

-showcerts çıktısındaki sertifikaları sayın. Tek başına bir sertifika genellikle eksik bir ara sertifika anlamına gelir. SSL sertifika denetleyicisi sona erme tarihini, zincirin eksiksizliğini ve ana bilgisayar adı eşleşmesini tek seferde raporlar; SSL sertifika zinciri nedir yazısı ara sertifikanın neden bu kadar önemli olduğunu açıklar.

-servername seçeneğini koruyun: OpenSSL 1.1.1 ve sonrası SNI'yı -connect ana bilgisayar adından doldurur, ancak macOS ile gelen LibreSSL openssl bunu yapmaz ve bir IP adresine bağlandığınızda hiçbir sürüm yapmaz. SNI olmadan paylaşımlı bir sunucu size varsayılan sertifikasını verir ya da Cloudflare gibi el sıkışmasını keser ve var olmayan bir ad uyuşmazlığının peşine düşersiniz.

Katman 4: Yanıt başlıklarını okuyun

TLS iyi, yani sonunda gerçek bir HTTP konuşmanız var. Şimdi istemcinizin sizin için özetlediğini değil, sunucunun gerçekte ne söylediğini okuyun. Yalnızca başlıkları yazdırın: gövde yine de indirilip atılır, yani bu, istemcinizin gönderdiği GET'in aynısıdır.

bash
curl -s -D - -o /dev/null https://waqtazan.com/api/v1/timings/egypt/cairo

Önce durum satırını, sonra content-type'ı, sonra geri kalanı okuyun. Bu iki alan, başka bir şey okumadan önce isteğin başarılı olup olmadığını ve gövdenin JSON olup olmadığını söyler.

Sağlıklı bir JSON yanıtı nasıl görünür

Yukarıdaki komutu 27 Ekim 2026'da test endpoint'ine karşı çalıştırmak, diğerlerinin yanı sıra şu başlıkları döndürdü:

BaşlıkDeğerSize ne söyler
HTTP/2200İstek başarılı oldu ve sunucu HTTP/2 konuşuyor
content-typeapplication/jsonHTML hata sayfası değil, JSON alacaksınız
content-length567Boş bir gövde değil, gerçek bir payload
access-control-allow-origin*Tarayıcıların bu yanıtı okumasına izin var
servercloudflareKaynağın önünde bir CDN var
alt-svch3=":443"Sonraki istekler için HTTP/3 duyuruluyor

Katman 5: Yalnızca tarayıcı çağrılarını bozan başlık

Saatlerin kaybolduğu katman burasıdır, çünkü curl ile tarayıcının gerçekten ayrıştığı katmandır. CORS'u sunucu değil tarayıcı uygular. Access-Control-Allow-Origin eksikse sunucu yine de eksiksiz ve doğru bir 200 döndürür; tarayıcı yalnızca gövdeyi JavaScript'inize vermeyi reddeder.

Yani belirti şudur: curl kusursuz çalışır, Postman kusursuz çalışır ve tarayıcı konsolu isteğin CORS politikası tarafından engellendiğini söyler. Sunucuda hiçbir sorun yoktur. Yanıtta yalnızca bir başlık eksiktir.

Test endpoint'i access-control-allow-origin: * döndürür; bu yüzden herhangi bir origin'den yapılan sade bir fetch() çalışır:

javascript
// Run it in the console of a tab on a site without a strict CSP, such as example.com
// (this page's own CSP blocks it). It works there because ACAO is set to *
const r = await fetch('https://waqtazan.com/api/v1/timings/egypt/cairo')
console.log(await r.json())

Preflight tuzağı: Başlık ekleyene kadar çalışır

İkinci bir tuzak daha var ve bu endpoint onu güzel gösteriyor. Basit bir istek (özel başlıksız düz bir GET) başarılı olur. Ancak özel bir başlık eklediğiniz ya da Content-Type: application/json ile POST yaptığınız anda tarayıcı önce bir OPTIONS preflight gönderir ve preflight yanıtının kendi CORS başlıklarını taşıması gerekir (MDN).

Preflight'ı ayrı test edin, çünkü o farklı bir kod yolundan gelen farklı bir yanıttır:

bash
curl -s -D - -o /dev/null -X OPTIONS \
  -H 'Origin: https://example.com' \
  -H 'Access-Control-Request-Method: GET' \
  https://waqtazan.com/api/v1/timings/egypt/cairo

27 Ekim 2026 itibarıyla bu preflight, content-type: text/html ile bir 200 döndürüyor ve hiç access-control-allow-origin başlığı içermiyor; dolayısıyla düz GET sorunsuz çalışsa bile tarayıcıdan gelen preflight'lı bir istek engellenir.

Tuzak tam olarak budur: entegrasyonunuz geliştirmede çalışır, bir Authorization ya da X-Request-Id başlığı eklersiniz ve sunucu tarafında hiçbir değişiklik olmadan bozulur. Yalnızca herkese açık veriye ihtiyacınız varsa isteği basit tutun, çalışmaya devam eder.

Katman 6: Payload beklediğiniz biçimde mi?

Son katman, kodunuzun gerçekten önemsediği katmandır. Geçerli JSON'lu bir 200, bir alan yeniden adlandırıldıysa, bir tür sayıdan string'e döndüyse ya da bir zaman damgası ayrıştırmadığınız bir biçimde geliyorsa yine de sizi bozabilir.

Ayrıştırıcıyı yazmadan önce gerçek yanıta bakın. Bu endpoint hem görüntü için biçimlendirilmiş saatleri hem de ISO zaman damgalarını döndürür; kopyalamaya değer bir kalıp: yerelleştirilmiş string'ler insanlar içindir, ISO değerleri kod içindir:

json
{
  "city": { "slug": "riyadh", "name_ar": "الرياض", "name_en": "Riyadh" },
  "country": "saudi-arabia",
  "date": "2026-10-26",
  "times":    { "fajr": "4:38 ص", "dhuhr": "11:37 ص", "maghrib": "5:17 م" },
  "timesISO": { "fajr": "2026-10-26T01:38:00.000Z", "dhuhr": "2026-10-26T08:37:00.000Z" },
  "method": "umm_al_qura"
}

Her zaman makinece okunabilir alanı ayrıştırın. Burada bu timesISO demektir, asla times değil: görüntü string'leri yerelleştirilmiştir ve yerel ayar değiştiği anda biçimleri değişir.

Yapıyı hızlıca incelemek için yanıtı jq'ya aktarın: curl -s <url> | jq keys üst düzey alanları listeler, jq '.times' ise ham gövdeyi kaydırmadan içine iner.

Belirti → katman → araç

Her seferinde altısını da yürümek yerine doğrudan önemli katmana atlamak için bunu kullanın:

GördüğünüzBaşarısız katmanŞununla kontrol edin
ERR_NAME_NOT_RESOLVED, ENOTFOUND1 — DNSDNS sorgusu
ECONNREFUSED, anında hata2 — PortPort denetleyicisi
İstek takılır, sonra zaman aşımına uğrar2 — Filtrelenen portPort denetleyicisi
CERT_HAS_EXPIRED, UNABLE_TO_VERIFY_LEAF_SIGNATURE3 — TLSSSL denetleyicisi
Tarayıcıda çalışır, curl veya Node'da başarısız olur3 — Eksik zincirSSL denetleyicisi
401, 429, 5034 — HTTP durumuHTTP Başlık Kontrolü
curl'de çalışır, tarayıcıda engellenir5 — CORSHTTP Başlık Kontrolü
Unexpected token '<', "<!DOCTYPE "... is not valid JSON4 — HTML hata sayfasıHTTP Başlık Kontrolü
Eksik veya yanlış türde alanlar6 — Payloadcurl … | jq

Gecikme bu merdivenin biraz dışında kalır. Tüm katmanlar geçiyor ama yanıtlar yavaşsa, ana bilgisayara gidiş dönüş süresini ping ile ölçün ve ad çözümlemenin kendisinin darboğaz olup olmadığını bir DNS hız testi ile kontrol edin.

Herhangi bir endpoint'in gerçek yanıt başlıklarını görün

Bir API'nin döndürdüğü kesin durum kodunu, content-type ve CORS başlıklarını görün. İstek sunucu tarafından yapılır, bu yüzden tarayıcı önbelleği veya eklentiler sonucu bozamaz. Ücretsiz, kayıt gerekmez.

Kaynaklar

  1. Cross-Origin Resource Sharing (CORS), MDN
  2. Fetch Standard: CORS-safelisted request headers, WHATWG

Sıkça Sorulan Sorular

Postman olmadan bir API endpoint'i nasıl test edilir?

Temel testlerde Postman'in yaptığı her şeyi curl karşılar. Yalnızca yanıt başlıklarını görmek için curl -s -D - -o /dev/null <url>, JSON gövdesini incelemek için curl -s <url> | jq ve yalnızca durum kodunu yazdırmak için curl -s -o /dev/null -w '%{http_code}' kullanın. Hiç terminal olmadan hızlı bir kontrol için çevrimiçi bir HTTP başlık denetleyicisi aynı bilgiyi tarayıcıdan döndürür.

API'm neden curl'de çalışıyor ama tarayıcıda başarısız oluyor?

Neredeyse her zaman CORS yüzündendir. Sunucu her iki durumda da geçerli bir yanıt döndürür, ancak yanıt origin'inize izin veren bir Access-Control-Allow-Origin başlığı taşımadıkça tarayıcılar gövdeyi JavaScript'e açmayı reddeder. curl, CORS'u tamamen yok sayar, çünkü CORS sunucunun değil tarayıcının güvenlik politikasıdır. Başlık eksikse onu sunucunun göndermesi gerekir: istemci tarafında bir çözüm yoktur.

curl'ün 000 durum kodu döndürmesi ne anlama gelir?

Hiçbir HTTP yanıtının alınmadığı, dolayısıyla raporlanacak bir durum kodu olmadığı anlamına gelir. Genellikle hata HTTP'den önce olmuştur: DNS çözümlenmedi, TCP bağlantısı reddedildi veya filtrelendi ya da TLS el sıkışması başarısız oldu. Bağlantıyı kabul edip sonra kapatan veya hiç yanıt vermeyen bir sunucu da 000 verir; bu yüzden çalışan son adımı görmek için komutu -v ile yeniden çalıştırın.

Bir API'nin herkes için mi yoksa sadece benim için mi kapalı olduğunu nasıl anlarım?

Kendi ağınızın dışından test edin. Sunucu tarafında çalışan bir port denetleyicisi ve DNS sorgusu; yerel çözümleyicinizi, VPN'inizi, kurumsal güvenlik duvarınızı ve tarayıcı önbelleğinizi denklemden çıkarır. Endpoint dış bir denetleyiciden yanıt veriyor ama makinenizden vermiyorsa sorun yereldir: genellikle DNS önbelleği veya bir güvenlik duvarı kuralı.

Bir API neden 200 döndürüyor ama JSON ayrıştırıcım hata veriyor?

Büyük olasılıkla 200 durumuyla HTML alıyorsunuz. Captive portal'lar, proxy'ler ve bazı hata sayfaları, HTML gövdeli bir başarı kodu döndürür. content-type başlığına bakın: application/json yerine text/html yazıyorsa gövde bir web sayfasıdır ve ayrıştırma hatası nedenin değil belirtinin kendisidir.

CORS preflight nedir ve ne zaman olur?

Preflight, istek "basit" olmadığında tarayıcının gerçek istekten önce otomatik olarak gönderdiği bir OPTIONS isteğidir: GET, HEAD veya POST dışında bir yöntem kullanır, Authorization gibi özel başlıklar ayarlar ya da form verisi veya düz metin dışında bir Content-Type gönderir (application/json buna dahildir). Preflight yanıtının kendisi de CORS başlıklarını içermelidir. Bu yüzden bir entegrasyon, bir kimlik doğrulama başlığı ekleyene kadar sorunsuz çalışabilir ve sonra sunucuda hiçbir değişiklik olmadan bozulur.

API'nin DNS'ini kendi çözümleyicimle mi yoksa herkese açık bir çözümleyiciyle mi test etmeliyim?

İkisiyle de test edip karşılaştırın. İSS'nizin çözümleyicisi, yetkili kayıt değiştikten çok sonra bile eski bir önbellek kaydı sunabilir. Varsayılan çözümleyicinizin yanında 1.1.1.1 ve 8.8.8.8'i de sorgulamak, bir yayılma gecikmesine mi yoksa gerçekten eksik bir kayda mı baktığınızı gösterir.

443 portunun açık olması HTTPS endpoint'inin çalıştığı anlamına gelir mi?

Hayır. Açık bir port yalnızca bir şeyin TCP bağlantısını kabul ettiğini doğrular. TLS el sıkışması yine de sertifikanın süresi dolduğu, ana bilgisayar adı eşleşmediği veya ara zincir eksik olduğu için başarısız olabilir. Portun açık olduğunu doğruladıktan sonra sertifikayı ayrıca kontrol edin.

Yazar hakkında

Shaik Vahid

DNS Robot'un kurucusu. Vahid, yıllarca web hosting desteğinde müşterilerin alan adı, DNS kaydı, SSL sertifikası ve e-posta teslimi sorunlarını çözdü. DNS Robot'un araçlarını geliştiriyor ve bu rehberleri insanların gerçekten karşılaştığı hatalardan yola çıkarak yazıyor.

HTTP Başlık Kontrolü

HTTP yanıt başlıklarını ve güvenlik başlıkları derecelendirmesini analiz edin