Modern web uygulamaları geliştirirken, sunucu tarafında dış kaynaklardan veri çekmek veya bu kaynaklara veri göndermek kaçınılmaz bir ihtiyaçtır. Node.js, asenkron yapısı ve güçlü ekosistemi sayesinde bu tür API etkileşimleri için ideal bir platform sunar. Bu makale, Node.js ortamında Fetch API’yi gerçek dünya verileriyle nasıl kullanacağınızı adım adım açıklayarak, hem yeni başlayanların hem de deneyimli geliştiricilerin bu konudaki bilgi birikimini artırmayı hedeflemektedir.
Node.js ile API etkileşimlerine dalmadan önce, bu üç temel kavramı netleştirmekte fayda var. Sonuçta, bir binanın temelini anlamadan katlarını inşa etmek pek de akıllıca olmaz, değil mi?
Node.js Nedir ve Neden Önemlidir?
Node.js, Google’ın V8 JavaScript motoru üzerine kurulu, sunucu tarafında JavaScript çalıştırmanıza olanak tanıyan açık kaynaklı, çalışma zamanı bir ortamdır. Geleneksel olarak JavaScript sadece tarayıcıda çalışırken, Node.js bu sınırı kaldırarak geliştiricilere tek bir dil (JavaScript) ile hem ön yüzü hem de arka yüzü geliştirme imkanı sunar. Bu durum, özellikle tam yığın (full-stack) geliştiriciler için büyük bir kolaylık ve verimlilik artışı demektir. Node.js’in en önemli özelliklerinden biri, olay tabanlı (event-driven) ve bloklamayan (non-blocking) G/Ç (Input/Output) modelidir. Bu sayede, aynı anda binlerce bağlantıyı verimli bir şekilde yönetebilir, bu da onu yüksek performanslı ve ölçeklenebilir ağ uygulamaları için mükemmel bir seçim haline getirir. Örneğin, bir web sunucusu düşünün; Node.js, bir isteği işlerken diğerlerini bekletmek yerine, tüm istekleri eş zamanlı olarak dinleyebilir ve her biri için uygun olduğunda yanıt verebilir. Bu asenkron yapı, özellikle ağ istekleri gibi zaman alıcı işlemler için kritik öneme sahiptir.
API Nedir ve Uygulama Geliştirmedeki Rolü?
API (Application Programming Interface), farklı yazılım sistemlerinin birbiriyle iletişim kurmasını sağlayan kurallar ve protokoller bütünüdür. Basitçe ifade etmek gerekirse, bir API, iki uygulamanın “konuşması” için bir köprü görevi görür. Örneğin, bir mobil uygulama hava durumu verilerini göstermek istediğinde, doğrudan hava durumu sensörlerine erişemez. Bunun yerine, bir hava durumu servisinin API’sini kullanarak bu bilgilere erişir. Günümüzde en yaygın API türlerinden biri REST (Representational State Transfer) API’dir. REST API’leri, HTTP protokolünü kullanarak veri alışverişi yapar ve kaynakları URL’ler aracılığıyla temsil eder. Temel HTTP metotları olan GET (veri alma), POST (veri gönderme), PUT (veri güncelleme) ve DELETE (veri silme) bu etkileşimin omurgasını oluşturur. Bir API’yi doğru bir şekilde anlamak ve kullanmak, modern yazılım mimarisinde modülerlik, esneklik ve yeniden kullanılabilirlik açısından hayati önem taşır. Birçok şirket, kendi verilerini veya hizmetlerini üçüncü taraf geliştiricilere açmak için API’ler sunar, bu da inovasyonu ve entegrasyonu teşvik eder.
Fetch API: Modern HTTP İstek Yönetimi
Fetch API, web tarayıcılarında HTTP istekleri yapmak için modern ve güçlü bir arayüzdür. Geleneksel XMLHttpRequest (XHR) yöntemine kıyasla daha esnek, vaat (Promise) tabanlı bir yapı sunar. Bu, asenkron işlemleri yönetmeyi çok daha kolay ve okunabilir hale getirir. Tarayıcılarda doğal olarak bulunan Fetch API, Node.js ortamında doğrudan yerleşik değildir. Ancak endişelenmeyin! Node.js topluluğu bu eksikliği gidermek için node-fetch gibi kütüphaneler geliştirmiştir. node-fetch, tarayıcıdaki Fetch API ile neredeyse aynı arayüze sahip olup, Node.js projelerinizde dış API’lerle etkileşim kurmanızı sağlar. Vaat tabanlı yapısı sayesinde, bir API isteği gönderdiğinizde, yanıtın gelmesini beklerken uygulamanızın diğer kısımlarının çalışmaya devam etmesini sağlar. Bu asenkron doğa, özellikle kullanıcı deneyimi açısından kritik öneme sahiptir, çünkü uzun süren bir ağ isteği tüm uygulamanızı kilitlemez. async/await söz dizimi ile birleştiğinde ise, asenkron kod yazmak adeta senkron kod yazmak kadar doğal ve anlaşılır bir hale gelir.
Node.js Ortamında API Çağrısı Nasıl Yapılır? İlk Adımlar
Şimdi teorik bilgileri pratiğe dökmeye hazırız. Node.js projenizde dış bir API’den veri çekmek için izlemeniz gereken adımlar oldukça basittir. Bu bölümde, projenizi nasıl kuracağınızı, node-fetch kütüphanesini nasıl ekleyeceğinizi ve basit bir GET isteğiyle ilk API çağrınızı nasıl yapacağınızı anlatacağız.
Node.js Projesini Başlatma ve Bağımlılıkları Kurma
Her şeyden önce, yeni bir Node.js projesi başlatmamız gerekiyor. Bunun için terminalinizde veya komut istemcinizde yeni bir klasör oluşturun ve içine girin:
mkdir nodejs-fetch-ornek
cd nodejs-fetch-ornek
Ardından, npm init -y komutuyla yeni bir package.json dosyası oluşturun. -y bayrağı, tüm sorulara varsayılan yanıtları vermenizi sağlar, bu da süreci hızlandırır:
npm init -y
Şimdi, Node.js ortamında Fetch API'sini kullanmamızı sağlayacak olan node-fetch kütüphanesini kurmalıyız:
npm install node-fetch@2 # node-fetch v3 ve üzeri sadece ES Modülleri ile çalışır, v2 yaygın kullanım için daha uygun.
Kurulum tamamlandığında, package.json dosyanızda "node-fetch": "^2.6.7" gibi bir girdi göreceksiniz. Bu, kütüphanenin başarıyla kurulduğunu gösterir.
Basit Bir GET İsteği Yapma: JSONPlaceholder Örneği
İlk API çağrımızı yapmak için popüler bir sahte REST API servisi olan JSONPlaceholder'ı kullanacağız. Bu servis, test ve prototipleme amaçları için sahte veriler sunar. Örneğin, https://jsonplaceholder.typicode.com/posts/1 adresinden bir gönderi çekebiliriz.
Proje klasörünüzde app.js adında yeni bir dosya oluşturun ve aşağıdaki kodu içine yapıştırın:
const fetch = require('node-fetch'); // node-fetch v2 için require kullanılır
async function getSinglePost() {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
if (!response.ok) { // HTTP yanıtının başarılı olup olmadığını kontrol edin (örn. 200 OK)
throw new Error(HTTP Hata kodu: ${response.status});
}
const data = await response.json(); // Yanıtı JSON formatında ayrıştırın
console.log('Başarıyla çekilen veri:', data);
} catch (error) {
console.error('Veri çekilirken bir hata oluştu:', error);
}
}
getSinglePost();
Bu kod bloğu, async/await söz dizimini kullanarak asenkron bir işlemi nasıl yöneteceğimizi gösterir. fetch fonksiyonu bir Promise döndürür, await anahtar kelimesi ise Promise'in çözülmesini bekler ve değeri döner. İlk await fetch(...) satırı, API'ye isteği gönderir ve yanıt (response) nesnesini bekler. Ardından, response.json() metodu yanıt gövdesini JSON olarak ayrıştırır ve bu da bir Promise döndürdüğü için tekrar await ile bekleriz. try...catch bloğu, ağ hataları veya API'den gelen başarısız yanıtlar gibi olası hataları yakalamak için kritik öneme sahiptir.
Bu kodu çalıştırmak için terminalinizde aşağıdaki komutu kullanın:
node app.js
Çıktıda, JSONPlaceholder'dan gelen ilk gönderinin detaylarını görmelisiniz. Bu, ilk başarılı Node.js API çağrınızdır!
node-fetch'in 3. sürümü ve üzeri sadece ES Modülleri (ESM) ile uyumludur. Eğer Node.js projenizde type: "module" tanımlaması yaptıysanız, import fetch from 'node-fetch'; şeklinde kullanmanız gerekir. Eski CommonJS modül yapısında (yani package.json dosyanızda "type": "module" yoksa) const fetch = require('node-fetch'); kullanmak için node-fetch@2 kurmanız önerilir.
Gerçek Dünya Verileriyle Çalışmak: Bir Vaka Analizi
Şimdiye kadar temel bir API çağrısı yapmayı öğrendik. Ancak gerçek dünya senaryoları genellikle daha karmaşık ve spesifik ihtiyaçlar içerir. Bu bölümde, gerçek bir API kullanarak hava durumu verisi çekme örneği üzerinden, API'lerle nasıl daha etkili çalışılacağını, parametre yönetimini ve elde edilen verinin nasıl işleneceğini detaylı bir şekilde inceleyeceğiz.
Örnek Senaryo: Bir Şehrin Hava Durumu Bilgilerini Çekme
Hava durumu uygulamaları, dış API'lerle etkileşimin en yaygın örneklerinden biridir. OpenWeatherMap gibi servisler, coğrafi konuma veya şehir adına göre güncel hava durumu verilerini sunar. Bu örneğimizde, belirli bir şehrin mevcut hava durumu bilgilerini çekeceğiz. Bu işlem, genellikle API anahtarı gerektiren kimlik doğrulama, sorgu parametreleri oluşturma ve alınan veriyi anlamlı bir şekilde ayrıştırma adımlarını içerir.
Adım 1: API Anahtarı Edinme ve Temel Kurulum
OpenWeatherMap gibi birçok gerçek dünya API'si, istekleri kimlik doğrulamak ve kötüye kullanımı önlemek için bir API anahtarı (API Key) gerektirir. OpenWeatherMap web sitesine kaydolduktan sonra ücretsiz bir API anahtarı edinebilirsiniz. Bu anahtarı, isteklerinizle birlikte göndermeniz gerekecektir.
API anahtarınızı doğrudan kodunuzun içine yazmak yerine, güvenlik ve esneklik açısından ortam değişkenleri (environment variables) kullanmak en iyi pratiktir. Bunun için dotenv kütüphanesini kullanabiliriz:
npm install dotenv
Projenizin ana dizininde .env adında bir dosya oluşturun ve API anahtarınızı aşağıdaki gibi ekleyin:
OPENWEATHER_API_KEY=sizin_open_weather_api_anahtariniz
Şimdi, app.js dosyanızın en üstüne dotenv'i yükleyin:
require('dotenv').config(); // Ortam değişkenlerini yükle
const fetch = require('node-fetch'); // node-fetch v2 için
const API_KEY = process.env.OPENWEATHER_API_KEY; // .env dosyasından anahtarı al
const BASE_URL = 'http://api.openweathermap.org/data/2.5/weather';
Bu yapı sayesinde, API anahtarınız kod tabanınızdan ayrı tutulur ve versiyon kontrol sistemlerine (örn. Git) yanlışlıkla yüklenmesi önlenir. Ayrıca, farklı ortamlar (geliştirme, üretim) için farklı anahtarlar kullanmanızı kolaylaştırır.
Adım 2: Parametreli GET İsteği Yapma ve Veriyi İşleme
OpenWeatherMap API'sinden bir şehrin hava durumunu çekmek için genellikle şehrin adını ve API anahtarını sorgu parametreleri olarak göndermemiz gerekir. URL'yi doğru bir şekilde oluşturmak önemlidir.
Aşağıdaki kodu app.js dosyanıza ekleyin:
async function getWeather(city) {
if (!API_KEY) {
console.error('Hata: OPENWEATHER_API_KEY ortam değişkeni ayarlanmamış.');
return;
}
const url = ${BASE_URL}?q=${city}&appid=${API_KEY}&units=metric&lang=tr; // Celsius ve Türkçe dil desteği
try {
console.log("${city}" için hava durumu verileri çekiliyor...);
const response = await fetch(url);
if (!response.ok) {
// API'den gelen spesifik hata mesajlarını da yakalayabiliriz
const errorData = await response.json();
throw new Error(API hatası: ${response.status} - ${errorData.message || 'Bilinmeyen Hata'});
}
const data = await response.json();
displayWeather(data); // Veriyi ekrana bastıran yardımcı fonksiyon
} catch (error) {
console.error('Hava durumu verisi çekilirken bir hata oluştu:', error.message);
}
}
function displayWeather(weatherData) {
if (!weatherData || weatherData.cod === '404') {
console.log('Belirtilen şehir bulunamadı.');
return;
}
const cityName = weatherData.name;
const country = weatherData.sys.country;
const temperature = weatherData.main.temp;
const description = weatherData.weather[0].description;
const humidity = weatherData.main.humidity;
const windSpeed = weatherData.wind.speed;
console.log(\nŞehir: ${cityName}, ${country});
console.log(Sıcaklık: ${temperature}°C);
console.log(Durum: ${description});
console.log(Nem Oranı: %${humidity});
console.log(Rüzgar Hızı: ${windSpeed} m/s);
}
// Hava durumu bilgisini almak istediğiniz şehri belirtin
getWeather('Istanbul'); // Örneğin İstanbul için hava durumu
getWeather('London'); // Farklı bir şehir için
getWeather('NonExistentCity'); // Olmayan bir şehir için hata yönetimi
Bu örnekte, getWeather fonksiyonu, dinamik olarak bir şehir adı alır ve bu ismi URL'ye ekler. Ayrıca units=metric ile sıcaklık birimini Celsius olarak, lang=tr ile de yanıt dilini Türkçe olarak belirtiyoruz. displayWeather fonksiyonu, çekilen JSON verisini daha okunabilir bir formatta konsola basar. Özellikle response.ok kontrolü ve API'nin kendi hata mesajlarını yakalama, daha sağlam bir hata yönetimi sağlar.
Bu kodu çalıştırdığınızda (önceki getSinglePost() çağrısını yorum satırı yapmayı unutmayın), İstanbul ve Londra'nın hava durumu bilgilerini, ayrıca "NonExistentCity" için bir hata mesajını görmelisiniz. Bu vaka analizi, gerçek dünya API'leriyle çalışmanın temel dinamiklerini ve hata yönetiminin önemini göstermektedir.
Veri Gönderme İşlemleri: POST, PUT ve DELETE Nasıl Yapılır?
API'lerle etkileşim sadece veri çekmekle sınırlı değildir. Çoğu zaman, bir sunucuya yeni veri eklememiz, mevcut veriyi güncellememiz veya silmemiz gerekir. Bu işlemler genellikle HTTP'nin POST, PUT ve DELETE metotları kullanılarak gerçekleştirilir. Bu bölümde, node-fetch ile bu metotları nasıl kullanacağımızı ve özellikle JSON formatında veri göndermenin inceliklerini ele alacağız.
POST İsteği ile Sunucuya Yeni Veri Ekleme
POST metodu, sunucuya yeni bir kaynak oluşturmak için kullanılır. Örneğin, bir blog uygulamasına yeni bir gönderi eklemek veya bir kullanıcı kaydetmek gibi işlemler POST isteğiyle yapılır. POST istekleri, genellikle istek gövdesinde (request body) gönderilecek veriyi taşır.
Yine JSONPlaceholder API'sini kullanarak yeni bir gönderi oluşturalım:
async function createPost() {
const newPost = {
title: 'Node.js ile Fetch API Denemesi',
body: 'Bu, Node.js kullanarak bir API\'ye gönderilen deneme bir yazıdır.',
userId: 1,
};
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST', // HTTP metodunu belirtiyoruz
headers: {
'Content-Type': 'application/json', // Gönderdiğimiz verinin türünü belirtiyoruz
},
body: JSON.stringify(newPost), // JS objesini JSON string'ine dönüştürüyoruz
});
if (!response.ok) {
throw new Error(HTTP Hata kodu: ${response.status});
}
const createdPost = await response.json();
console.log('\nYeni gönderi başarıyla oluşturuldu:', createdPost);
console.log('API genellikle oluşturulan kaynağa bir ID atar:', createdPost.id);
} catch (error) {
console.error('Gönderi oluşturulurken bir hata oluştu:', error);
}
}
createPost();
Burada dikkat etmeniz gereken noktalar:
method: 'POST': İstek tipini POST olarak belirtiriz.headers: { 'Content-Type': 'application/json' }: Sunucuya, istek gövdesinin JSON formatında olduğunu bildiririz. Bu başlık, çoğu REST API için kritik öneme sahiptir.body: JSON.stringify(newPost): JavaScript objemizi (newPost), API'nin anlayacağı JSON string formatına dönüştürürüz. Bu adım hayati bir adımdır, çünkü ağ üzerinden direkt JavaScript objeleri gönderilemez.
JSONPlaceholder, gerçekte bir veri tabanına yazma işlemi yapmaz; ancak başarılı bir POST isteğine benzer şekilde, gönderilen veriye bir id atayarak bir yanıt döner.
PUT ve DELETE İstekleri ile Veri Güncelleme ve Silme
PUT metodu, mevcut bir kaynağı tamamen güncellemek için kullanılırken, PATCH metodu kaynağın sadece belirli bir kısmını güncellemek için tercih edilir. DELETE metodu ise, adından da anlaşılacağı gibi, belirli bir kaynağı sunucudan silmek için kullanılır.
PUT İsteği (Veri Güncelleme)
Mevcut bir gönderiyi güncelleyelim. Genellikle, güncellenecek kaynağın ID'si URL içinde belirtilir:
async function updatePost(postId) {
const updatedData = {
title: 'Güncellenmiş Başlık: Node.js ve Fetch API',
body: 'Bu gönderi, Node.js fetch ile güncellendi.',
userId: 1, // userId'yi koruyabilir veya değiştirebiliriz
};
try {
const response = await fetch(https://jsonplaceholder.typicode.com/posts/${postId}, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(updatedData),
});
if (!response.ok) {
throw new Error(HTTP Hata kodu: ${response.status});
}
const result = await response.json();
console.log(\nGönderi ${postId} başarıyla güncellendi:, result);
} catch (error) {
console.error(Gönderi ${postId} güncellenirken bir hata oluştu:, error);
}
}
updatePost(1); // ID'si 1 olan gönderiyi güncelle
PUT isteği de POST gibi body ve Content-Type başlığı gerektirir.
DELETE İsteği (Veri Silme)
Bir kaynağı silmek için DELETE metodu kullanılır. Bu istek genellikle bir gövde taşımaz:
async function deletePost(postId) {
try {
const response = await fetch(https://jsonplaceholder.typicode.com/posts/${postId}, {
method: 'DELETE',
});
if (!response.ok) {
throw new Error(HTTP Hata kodu: ${response.status});
}
// DELETE isteği genellikle boş bir yanıt gövdesi veya başarı durumu döner
console.log(\nGönderi ${postId} başarıyla silindi.);
// Eğer API bir yanıt gövdesi döndürüyorsa, onu da ayrıştırabiliriz:
// const result = await response.json();
// console.log(result);
} catch (error) {
console.error(Gönderi ${postId} silinirken bir hata oluştu:, error);
}
}
deletePost(1); // ID'si 1 olan gönderiyi sil
DELETE isteğinde, sunucudan başarılı bir yanıt aldığımızda (genellikle 200 OK veya 204 No Content), işlemin başarılı olduğunu varsayabiliriz. Çoğu durumda, DELETE istekleri bir yanıt gövdesi döndürmez.
Bu bölüm, Node.js ile Fetch API kullanarak sadece veri çekmekle kalmayıp, aynı zamanda sunucu tarafında veri oluşturma, güncelleme ve silme gibi temel CRUD (Create, Read, Update, Delete) işlemlerini nasıl gerçekleştireceğinizi göstermektedir. Bu, dinamik ve etkileşimli uygulamalar geliştirmenin anahtarıdır.
Performans ve Güvenlik İpuçları: İleri Düzey Kullanım
Node.js ile API etkileşimlerinde başarılı olmak sadece doğru kod yazmakla bitmez; aynı zamanda performansı optimize etmek ve güvenlik açıklarını önlemek de büyük önem taşır. Bu bölümde, deneyimli geliştiriciler için kritik ipuçlarını ve püf noktalarını ele alacağız.
API Yanıtlarını Önbelleğe Alma (Caching)
Sıkça talep edilen veriler için her defasında API isteği yapmak hem sunucunuza ek yük bindirir hem de uygulamanızın yanıt süresini uzatır. Bu tür durumlar için önbelleğe alma (caching) stratejileri uygulamak performansı önemli ölçüde artırabilir. Örneğin, bir hava durumu API'sinden çektiğiniz veriler genellikle birkaç dakika boyunca geçerlidir. Bu verileri yerel bir bellekte (örneğin, Node.js uygulamanızın kendi belleğinde veya Redis gibi bir in-memory veri tabanında) tutarak, belirli bir süre boyunca aynı istek geldiğinde API'ye tekrar gitmek yerine önbellekten servis edebilirsiniz.
const cache = {}; // Basit bir bellek içi önbellek
const CACHE_DURATION = 5 * 60 * 1000; // 5 dakika (milisaniye cinsinden)
async function getWeatherDataWithCache(city) {
const cacheKey = weather_${city};
const now = Date.now();
if (cache[cacheKey] && (now - cache[cacheKey].timestamp < CACHE_DURATION)) {
console.log(\nÖnbellekten "${city}" hava durumu verileri servis edildi.);
displayWeather(cache[cacheKey].data);
return;
}
// Önbellekte yoksa veya süresi dolduysa, API'den çek
try {
const API_KEY = process.env.OPENWEATHER_API_KEY;
const BASE_URL = 'http://api.openweathermap.org/data/2.5/weather';
const url = ${BASE_URL}?q=${city}&appid=${API_KEY}&units=metric&lang=tr;
console.log(API'den "${city}" hava durumu verileri çekiliyor...);
const response = await fetch(url);
if (!response.ok) {
const errorData = await response.json();
throw new Error(API hatası: ${response.status} - ${errorData.message || 'Bilinmeyen Hata'});
}
const data = await response.json();
cache[cacheKey] = { data: data, timestamp: now }; // Veriyi önbelleğe al
displayWeather(data);
} catch (error) {
console.error('Hava durumu verisi çekilirken bir hata oluştu (önbelleksiz):', error.message);
}
}
getWeatherDataWithCache('Paris');
setTimeout(() => getWeatherDataWithCache('Paris'), 1 * 60 * 1000); // 1 dakika sonra tekrar iste, önbellekten gelir
setTimeout(() => getWeatherDataWithCache('Paris'), 6 * 60 * 1000); // 6 dakika sonra iste, API'den tekrar çeker
Bu basit önbellek mekanizması, aynı isteklerin tekrarlanmasını önleyerek API kota kullanımınızı da azaltabilir.
API Anahtarlarının Güvenli Yönetimi
Daha önce bahsettiğimiz gibi, API anahtarlarını doğrudan kodunuzda saklamak ciddi bir güvenlik riskidir. Ortam değişkenleri (.env dosyası ve dotenv kütüphanesi) bu sorunu çözmek için harika bir yöntemdir. Ancak, üretim ortamında bu anahtarların daha da güvenli bir şekilde yönetilmesi gerekebilir. Kubernetes sırları (secrets), AWS Secrets Manager, HashiCorp Vault gibi araçlar, hassas bilgileri güvenli bir şekilde depolamak ve uygulamalarınıza dağıtmak için profesyonel çözümler sunar. Her zaman API anahtarlarınızı versiyon kontrol sistemlerine yüklemediğinizden emin olun (örn. .gitignore dosyasına .env ekleyin).
Hata Yönetimi ve Yeniden Deneme Mekanizmaları
Ağ istekleri doğası gereği başarısız olabilir: API sunucusu geçici olarak kapalı olabilir, ağ bağlantısı kesilebilir veya bir oran sınırı (rate limit) hatası alabilirsiniz. Sağlam bir uygulama, bu tür durumları ele almalı ve gerekirse isteği belirli bir gecikmeyle yeniden denemelidir (retry mechanism).
async function fetchWithRetry(url, options = {}, retries = 3, delay = 1000) {
for (let i = 0; i < retries; i++) {
try {
const response = await fetch(url, options);
if (response.ok) {
return response;
}
// Özellikle 429 Too Many Requests gibi hatalarda yeniden deneme yapabiliriz
if (response.status === 429 && i < retries - 1) {
console.warn(Oran sınırı hatası (${response.status}). ${delay / 1000} saniye bekleyip tekrar deniyorum...);
await new Promise(res => setTimeout(res, delay));
delay *= 2; // Gecikmeyi artırarak backoff stratejisi
continue;
}
throw new Error(HTTP Hata kodu: ${response.status});
} catch (error) {
if (i < retries - 1) {
console.warn(Ağ hatası: ${error.message}. ${delay / 1000} saniye bekleyip tekrar deniyorum...);
await new Promise(res => setTimeout(res, delay));
delay *= 2;
continue;
}
throw error; // Son denemede hala hata varsa, hatayı yukarıya fırlat
}
}
}
// Kullanım örneği
// fetchWithRetry('https://api.example.com/data')
// .then(response => response.json())
// .then(data => console.log('Veri:', data))
// .catch(error => console.error('Tüm denemeler başarısız oldu:', error));
Bu fetchWithRetry fonksiyonu, belirli bir sayıda deneme yapar ve her deneme arasında artan bir gecikme (exponential backoff) uygular. Bu, API'ye aşırı yük bindirmeden geçici sorunların üstesinden gelmeye yardımcı olur.
Zaman Aşımı (Timeout) Yönetimi
Bir API çağrısının çok uzun sürmesi, uygulamanızın performansını olumsuz etkileyebilir. Özellikle yanıt vermeyen veya yavaş API'lerle çalışırken zaman aşımı ayarlamak önemlidir. node-fetch doğrudan bir timeout seçeneği sunmaz, ancak bu functionality AbortController kullanılarak veya özel bir sarmalayıcı (wrapper) fonksiyonu ile sağlanabilir:
async function fetchWithTimeout(url, options = {}, timeout = 5000) { // 5 saniye
const controller = new AbortController();
const id = setTimeout(() => controller.abort(), timeout);
try {
const response = await fetch(url, {
...options,
signal: controller.signal
});
clearTimeout(id); // Zaman aşımı tetiklenmeden önce istek tamamlandı
return response;
} catch (error) {
clearTimeout(id);
if (error.name === 'AbortError') {
throw new Error('İstek zaman aşımına uğradı.');
}
throw error;
}
}
// Kullanım örneği (varsayılan 5sn timeout ile)
// fetchWithTimeout('https://slow-api.example.com/data', {}, 2000) // 2 saniye timeout
// .then(response => response.json())
// .then(data => console.log('Veri:', data))
// .catch(error => console.error('Hata:', error.message));
Bu fonksiyon, belirtilen süre içinde yanıt alınamazsa isteği iptal eder, böylece uygulamanızın askıda kalmasını engeller.
@media sorguları kullanarak farklı ekran boyutlarına uygun stiller tanımlamak, modern web geliştirmenin vazgeçilmez bir parçasıdır. Örneğin, sunduğunuz veriyi gösteren bir tablo için mobil cihazlarda kaydırılabilir bir yapı veya daha küçük ekranlarda kolonların alt alta sıralanması gibi çözümler düşünebilirsiniz.
/* Mobil cihazlar için örnek medya sorgusu */
@media (max-width: 768px) {
table {
display: block;
overflow-x: auto; /* Tablo geniş ekranı aştığında yatay kaydırma çubuğu */
white-space: nowrap;
}
/* Ya da kolonları alt alta sıralamak için */
/*
table tr {
display: block;
margin-bottom: 1em;
}
table td, table th {
display: block;
text-align: right;
}
table td::before {
content: attr(data-label);
float: left;
font-weight: bold;
text-transform: uppercase;
}
*/
}
Yukarıdaki CSS kodu, Node.js ile sunulan bir HTML sayfasında veya SPA (Single Page Application) bağlamında kullanıldığında, tabloların küçük ekranlarda daha iyi görünmesini sağlayabilir. Node.js'in rolü, bu tür ön yüzlerin ihtiyaç duyduğu veriyi sağlamaktır.
Sonuç ve Sıkça Sorulan Sorular
Bu makale boyunca, Node.js ortamında Fetch API'yi kullanarak dış servislerle nasıl etkileşim kuracağımızı detaylı bir şekilde inceledik. Temel GET isteklerinden, dinamik parametrelerle gerçek dünya verisi çekmeye, POST, PUT ve DELETE gibi veri manipülasyonu işlemlerine kadar birçok konuya değindik. Ayrıca, API entegrasyonlarınızın daha sağlam, güvenli ve performanslı olması için önbellekleme, hata yönetimi, yeniden deneme mekanizmaları ve zaman aşımı gibi ileri düzey konulara da odaklandık. Node.js'in asenkron yapısı ve node-fetch kütüphanesinin sağladığı kolaylıklar sayesinde, karmaşık API etkileşimlerini bile basit ve okunabilir bir şekilde yönetebiliriz. Unutmayın, pratik yapmak ve farklı API'leri keşfetmek bu alandaki yetkinliğinizi artırmanın en iyi yoludur. İyi kodlamalar!
Sıkça Sorulan Sorular (SSS)
Node.js'te Fetch API'yi neden kullanmalıyım?
Fetch API, vaat (Promise) tabanlı modern ve güçlü bir arayüz sunar. Bu, asenkron HTTP isteklerini async/await söz dizimiyle daha okunabilir ve yönetilebilir bir şekilde yazmanızı sağlar. XMLHttpRequest'e kıyasla daha basittir ve tarayıcıdaki kullanımına benzerliği sayesinde tutarlılık sunar.
node-fetch yerine başka hangi kütüphaneler var?
node-fetch, tarayıcı Fetch API'sinin Node.js portu olması nedeniyle popülerdir. Ancak Axios, Superagent gibi daha olgun ve zengin özelliklere sahip HTTP istemci kütüphaneleri de mevcuttur. Axios, özellikle otomatik JSON dönüştürme, isteği ve yanıtı yakalama (interceptors) gibi güçlü özellikleriyle öne çıkar.
API anahtarlarımı nasıl güvende tutabilirim?
API anahtarlarınızı asla doğrudan kodunuzda veya versiyon kontrol sistemlerinde (Git) saklamayın. Ortam değişkenleri (.env dosyası ve dotenv kütüphanesi ile), hassas verileri kod tabanınızdan ayırmak için basit ve etkili bir yöntemdir. Üretim ortamında ise Kubernetes Secrets, AWS Secrets Manager gibi daha gelişmiş gizli yönetim çözümleri kullanmanız önerilir.
Hata yönetimi için en iyi pratikler nelerdir?
Hata yönetiminde temel adımlar şunlardır: HTTP durum kodlarını kontrol etmek (response.ok), try...catch blokları kullanarak ağ ve uygulama seviyesi hataları yakalamak, kullanıcıya anlamlı hata mesajları sunmak ve gerekirse başarısız istekleri belirli bir gecikmeyle (backoff stratejisi ile) yeniden denemek.
Asenkron işlemler neden önemlidir?
Asenkron işlemler, bir uygulamanın uzun süreli görevleri (örneğin ağ istekleri, dosya okuma/yazma) ana iş parçacığını (main thread) bloke etmeden gerçekleştirmesini sağlar. Node.js'in tek iş parçacıklı ve olay döngüsü (event loop) tabanlı yapısında bu özellikle kritiktir. Aksi takdirde, bir API çağrısının yanıtını beklerken uygulamanız tamamen durur ve yanıt veremez hale gelir, bu da kötü bir kullanıcı deneyimine yol açar.
