- Katılım
- 7 Nis 2025
- Konular
- 367
- Mesajlar
- 780
- Çözümler
- 1
- Tepkime puanı
- 121
- Puan
- 93
- Konum
- İstanbul
- Web sitesi
- forumagel.com
Hazır Kod Bankası - Konu 25: Client-Side JavaScript ile Web API Tüketimi (Fetch API)
Hazır Kod Bankası Serimizin Yirmi Beşinci Konusu: JavaScript ile API Tüketimi!
Merhaba arkadaşlar! Web geliştirmede ön yüz (HTML, CSS) ve arka yüz (PHP, Python/Flask, Veritabanı, API) kavramlarını gördük. Konu 22-24'te kendi API backend'imizi (Flask+DB+Security) oluşturduk. Şimdi bu arka yüzü, ön yüzdeki uygulamalarla (Web tarayıcısında çalışan JavaScript gibi) nasıl bağlayacağımızı öğreneceğiz.
İstemci tarafındaki JavaScript kodunun, bir web sayfasını yeniden yüklemeye gerek kalmadan arka planda sunucuya (API'ye) istek gönderip veri alması veya göndermesi tekniğine AJAX (Asynchronous JavaScript and XML, artık sadece "Asenkron JavaScript" olarak düşünülür) denir. Bu, modern, dinamik ve hızlı yanıt veren web uygulamalarının (örneğin sosyal medya akışlarının otomatik güncellenmesi, ürün filtrelemenin sayfayı yeniden yüklememesi) temelini oluşturur.
AJAX işlemlerini gerçekleştirmek için modern JavaScript'te en yaygın ve önerilen yöntem Fetch API'dir. Fetch API, HTTP istekleri yapmak için esnek ve güçlü bir yol sunar ve Promise adı verilen yapılarla asenkron işlemleri yönetmeyi kolaylaştırır.
Bu konuda, tarayıcıda çalışan JavaScript kodları ile bir Web API'sine (örneğin Konu 23/24'te yaptığımız Flask API'si gibi) nasıl HTTP istekleri (GET, POST) göndereceğimizi, API'den gelen JSON formatındaki yanıtları nasıl alıp işleyeceğimizi ve bu verilere göre web sayfasını nasıl güncelleyeceğimizi göreceğiz.
Ön Gereksinim:
- Temel HTML (Konu 1) ve JavaScript (Konu 8) bilgisi olmalı.
- Test için çalışan bir Web API'ye (tercihen Konu 23/24'teki Flask API'si gibi JSON dönen bir API'ye) erişiminiz olmalı. (Bu API'nin güvenlik için API Key gerektirdiğini varsayarak örnek vereceğiz.)
- Kodları çalıştırmak için modern bir web tarayıcısı (Fetch API desteği için).
1. Fetch API İle Temel GET İsteği Gönderme[/B]
Fetch API, `Workspace()` global fonksiyonu ile kullanılır. En basit haliyle sadece URL alır ve bir Promise döndürür. Promise, işlemin gelecekte tamamlanacağını temsil eder. İşlem başarılı olursa `.then()`, hata olursa `.catch()` blokları çalışır.
JavaScript:
// API'mizin temel URL'si (Konu 23/24'teki Flask API'nizin adresi)
const API_URL = 'http://127.0.0.1:5000';
// Tüm ürünleri getiren API endpoint'ine GET isteği gönderme
fetch(API_URL + '/products') // fetch fonksiyonu bir Promise döner
.then(response => { // İstek başarılı olursa bu blok çalışır, response objesini alırız
// HTTP yanıtının başarılı olup olmadığını kontrol et (status kodu 2xx ise true)
if (!response.ok) {
// Hata durumunda response objesinden hata fırlat
// Bu hata .catch() bloğu tarafından yakalanır
throw new Error(`HTTP hata! Status: ${response.status}`);
}
// Yanıt body'sini JSON olarak oku ve parse et
// response.json() da bir Promise döner
return response.json();
})
.then(data => { // response.json() Promise'ı başarılı olursa bu blok çalışır, parse edilmiş JSON data'yı alırız
console.log('API\'den Gelen Veri:', data);
// Burada gelen veriyi kullanarak HTML sayfayı güncelleyebilirsiniz (DOM manipülasyonu)
})
.catch(error => { // İstek sırasında veya önceki .then bloklarında hata olursa bu blok çalışır
console.error('API isteği sırasında bir hata oluştu:', error);
// Kullanıcıya hata mesajı gösterebilirsiniz
});
console.log("Fetch isteği gönderildi, yanıt bekleniyor..."); // Asenkron olduğu için bu satır fetch'ten hemen sonra çalışır
2. JSON Yanıtını İşleme ve HTML Güncelleme[/B]
API'den gelen JSON veriyi aldıktan sonra (ikinci `.then()` bloğunda), bu veriyi kullanarak web sayfasının HTML içeriğini güncelleyebilirsiniz.
JavaScript:
// Önceki fetch GET isteği kodunun devamı...
fetch(API_URL + '/products')
.then(response => {
if (!response.ok) {
throw new Error(`HTTP hata! Status: ${response.status}`);
}
return response.json();
})
.then(data => {
console.log('Ürün Listesi:', data);
const productsListElement = document.getElementById('products-list'); // HTML'de id='products-list' olan bir elementiniz olmalı
// Listenin mevcut içeriğini temizle (isteğe bağlı)
productsListElement.innerHTML = '';
// Gelen her ürün için HTML oluştur ve listeye ekle
data.forEach(product => { // Gelen data'nın ürün objeleri listesi olduğunu varsayıyoruz
const listItem = document.createElement('li'); // Yeni bir liste elemanı (<li>) oluştur
listItem.textContent = `${product.ad} - ${product.fiyat} TL`; // Elemanın metin içeriğini ayarla (JSON'daki ad ve fiyatı kullan)
productsListElement.appendChild(listItem); // Oluşturulan li elementini HTML listesine ekle
});
})
.catch(error => {
console.error('Ürün listesi yüklenirken hata oluştu:', error);
const productsListElement = document.getElementById('products-list');
productsListElement.innerHTML = '<li>Ürünler yüklenemedi.</li>'; // Hata durumunda mesaj göster
});
3. Fetch API İle POST İsteği Gönderme (Veri Gönderme)[/B]
API'ye veri göndermek (örneğin form verileri) için `Workspace()` fonksiyonunun ikinci parametresi olan options objesini kullanırız. Metodu (`method`), başlıkları (`headers`) ve göndereceğimiz veriyi (`body`) bu objede belirtiriz.
JavaScript:
// Yeni ürün ekleme API endpoint'i (Örneğin Flask API'deki /products POST endpoint'i)
const ADD_PRODUCT_URL = API_URL + '/products'; // API_URL yukarıda tanımlı
// Eklenecek ürün verisi (Örneğin bir formdan alındı)
const yeniUrunData = {
ad: 'Yeni Kitap',
fiyat: 75.50
};
// API Key (Örneğin Konu 24'teki admin key)
const API_KEY = 'admin_super_key'; // Gerçek uygulamada bu değer güvenli saklanmalı
fetch(ADD_PRODUCT_URL, {
method: 'POST', // Metodu belirt
headers: {
'Content-Type': 'application/json', // Gönderilen verinin JSON olduğunu belirt
'X-API-Key': API_KEY // Güvenlik için API anahtarını başlık olarak gönder
// Gerekirse başka başlıklar eklenebilir (örn: Authorization)
},
body: JSON.stringify(yeniUrunData) // Python objesini/sözlüğünü JSON string'ine çevirip body'ye ekle
})
.then(response => {
if (!response.ok) {
// Hata durumunda (400, 401, 403, 404, 500 vb.)
// Hata detayını JSON olarak almak isteyebiliriz
return response.json().then(errorData => { // Hata body'sini de JSON olarak oku
throw new Error(`API Hatası! Status: ${response.status}, Mesaj: ${errorData.message || response.statusText}`);
});
}
return response.json(); // Başarılı yanıt body'sini JSON olarak oku
})
.then(data => {
console.log('Ürün Ekleme Başarılı:', data);
// Başarı mesajını gösterebilir, listeyi yeniden yükleyebilirsiniz
alert('Ürün başarıyla eklendi!');
// Ürün listesini güncellemek için: window.location.reload(); veya get_products() fonksiyonunu tekrar çağır
})
.catch(error => {
console.error('Ürün ekleme sırasında bir hata oluştu:', error);
alert('Ürün eklenirken hata oluştu: ' + error.message); // Kullanıcıya hata mesajı göster
});
console.log("Fetch POST isteği gönderildi, yanıt bekleniyor...");
4. HTML Form İle Entegrasyon (Örnek Uygulama)[/B]
Genellikle API'ye veri gönderme işlemi bir HTML formundan tetiklenir. Formun standart gönderimini (sayfa yenileme) engelleyip, form verilerini JavaScript ile alıp Fetch POST isteği göndermeliyiz.
index.html Dosyası:
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>API Tüketimi Örneği</title>
</head>
<body>
<h1>Ürünler</h1>
{# Ürün listesini göstereceğimiz alan #}
<h2>Ürün Listesi</h2>
<ul id="products-list">
<li>Ürünler yükleniyor...</li>
</ul>
<hr>
{# Yeni ürün ekleme formu #}
<h2>Yeni Ürün Ekle</h2>
<form id="add-product-form">
<label for="product-name">Ürün Adı:</label><br>
<input type="text" id="product-name" required><br><br>
<label for="product-price">Fiyat:</label><br>
<input type="number" id="product-price" step="0.01" required><br><br>
{# Güvenlik Notu: API Key'i HTML'e yazmak risklidir. Bu sadece örnek! #}
{# Normalde kimlik doğrulama farklı yönetilir. #}
<label for="api-key">API Key (Admin):</label><br>
<input type="text" id="api-key" value="admin_super_key" required><br><br>
<button type="submit">Ürünü Ekle</button>
</form>
[B]<script>[/B]
// JavaScript kodlarımız buraya gelecek
// Yukarıdaki 1, 2 ve 3. adımlardaki kodları buraya entegre edeceğiz
const API_URL = 'http://127.0.0.1:5000'; // API adresiniz
const productsListElement = document.getElementById('products-list');
const addProductForm = document.getElementById('add-product-form');
// Fonksiyon: Ürün listesini API'den çek ve sayfada göster
function fetchAndDisplayProducts() {
productsListElement.innerHTML = '<li>Ürünler yükleniyor...</li>'; // Yükleniyor mesajı
fetch(API_URL + '/products')
.then(response => {
if (!response.ok) {
return response.json().then(errorData => {
throw new Error(`API hata! Status: ${response.status}, Mesaj: ${errorData.message || response.statusText}`);
});
}
return response.json();
})
.then(data => {
productsListElement.innerHTML = ''; // Temizle
if (data.length === 0) {
productsListElement.innerHTML = '<li>Henüz ürün bulunamadı.</li>';
return; // Eğer ürün yoksa devam etme
}
data.forEach(product => {
const listItem = document.createElement('li');
listItem.textContent = `${product.ad} - ${product.fiyat} TL (ID: ${product.id})`;
productsListElement.appendChild(listItem);
});
})
.catch(error => {
console.error('Ürün listesi yüklenirken hata oluştu:', error);
productsListElement.innerHTML = '<li>Ürünler yüklenemedi. Hata: ' + error.message + '</li>';
});
}
// Fonksiyon: Form submit edildiğinde çalışır, API'ye POST isteği gönderir
function handleAddProductFormSubmit(event) {
event.preventDefault(); // Formun standart gönderimini (sayfa yenileme) engelle!
const productNameInput = document.getElementById('product-name');
const productPriceInput = document.getElementById('product-price');
const apiKeyInput = document.getElementById('api-key'); // API Key inputu
const productName = productNameInput.value;
const productPrice = parseFloat(productPriceInput.value); // Fiyatı sayıya çevir
const apiKey = apiKeyInput.value;
// Gönderilecek veri objesi
const newProductData = {
ad: productName,
fiyat: productPrice
};
fetch(API_URL + '/products', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': apiKey // API Key'i başlığa ekle
},
body: JSON.stringify(newProductData) // Veriyi JSON string'ine çevir
})
.then(response => {
// Yanıtın status kodunu kontrol et
if (!response.ok) {
return response.json().then(errorData => { // Hata body'sini oku
throw new Error(`API Hatası! Status: ${response.status}, Mesaj: ${errorData.message || response.statusText}`);
});
}
return response.json(); // Başarılı yanıt body'sini JSON olarak oku
})
.then(data => {
console.log('Ürün Ekleme Başarılı:', data);
alert('Ürün başarıyla eklendi: ' + data.product.ad);
// Formu temizle
productNameInput.value = '';
productPriceInput.value = '';
// Ürün listesini güncelle
fetchAndDisplayProducts();
})
.catch(error => {
console.error('Ürün ekleme sırasında hata oluştu:', error);
alert('Ürün eklenirken hata oluştu: ' + error.message);
});
}
// Sayfa yüklendiğinde ürün listesini çek ve göster
window.addEventListener('load', fetchAndDisplayProducts);
// Formun submit olayına fonksiyonu bağla
addProductForm.addEventListener('submit', handleAddProductFormSubmit);
[B]</script>[/B]
</body>
</html>
Sıra Sizde![/B]
Client-side JavaScript kullanarak bir API'yi tüketmenin temellerini ve HTML ile nasıl entegre edileceğini gördük.
- Konu 23/24'teki Flask API'nizin çalıştığından emin olun.
- Yukarıdaki `index.html` dosyasını oluşturun ve API_URL sabitini kendi API adresinizle güncelleyin.
- HTML dosyasını tarayıcınızda açın. Sayfa yüklendiğinde ürünlerin yüklenip yüklenmediğini (veya hata mesajını) kontrol edin (Tarayıcının konsolunu açın - F12).
- Formu kullanarak yeni bir ürün eklemeyi deneyin (Geçerli admin API Key'i girdiğinizden emin olun). Ürünün listeye eklendiğini doğrulayın.
- Geçersiz bir API Key veya eksik veri ile ekleme denemeleri yaparak hata mesajlarını gözlemleyin.
- Kendi API'nizdeki diğer endpoint'leri (örneğin DELETE endpoint'i) JavaScript ile Fetch kullanarak tüketmeyi deneyin.
Serinin Geleceği?[/B]
Ön yüz (Client-side JS) ile arka yüz (Web API) arasındaki bağlantıyı kurduk ve Fetch API ile veri alışverişi yapmayı öğrendik. Bu, dinamik web uygulamaları geliştirmenin çok önemli bir adımıdır.
Seriyi buradan sonra nasıl devam ettirelim?
- Fetch API'de daha ileri konular (Async/Await kullanımı, daha detaylı hata yönetimi, Fetch ile PUT/DELETE)?
- CORS (Cross-Origin Resource Sharing) kavramı ve API'ler ile frontend arasındaki bağlantıdaki önemi?
- JavaScript Frontend Frameworklerine giriş (React, Vue, Angular)?
- API Güvenliği ve Kimlik Doğrulama/Yetkilendirme konularında daha ileri adımlar (Token yönetimi - JWT)?
- Daha ileri Veri Yapıları ve Algoritma konuları?
- Başka bir programlama diline giriş (C#, C++ gibi)?
- Veya başka önerileriniz mi var?
Umarım bu konu, web uygulamalarınızın ön yüzünü arka yüzdeki API'lerle canlı hale getirme konusunda sizlere pratik bir bakış açısı sunmuştur. Görüşmek üzere!
Bu konu, "Hazır Kod Bankası" serisinin yirmi beşinci parçasıdır ve "Yazılım Bilgi ve Yeni Başlayanlar İçin" kategorisi altında paylaşılmıştır.