- 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 31: Vue.js ile API Verisi Güncelleme (POST, PUT, DELETE)
Hazır Kod Bankası Serimizin Otuz Birinci Konusu: Vue.js ile API Verisi Güncelleme (POST, PUT, DELETE)!
Merhaba arkadaşlar! Vue.js bileşenleri içinde API'den veri çekmeyi (GET istekleri) ve bu veriyi sayfada göstermeyi öğrendik (Vue.js ile Web API Çağrıları ve Veri Yönetimi (Fetch veya Axios)). Ancak çoğu uygulama, kullanıcının veri oluşturmasına (Create), güncellemesine (Update) veya silmesine (Delete) de olanak tanır. Bu işlemler için Web API'nin GET dışındaki metotları (POST, PUT, DELETE) kullanılır ve genellikle form gönderimleri veya buton tıklamaları gibi kullanıcı etkileşimleri sonucunda tetiklenirler.
Bu konuda, Vue.js bileşenlerinde kullanıcı etkileşimleri aracılığıyla API'ye POST, PUT ve DELETE istekleri göndermeyi, bu isteklere veri eklemeyi (POST/PUT için), yanıtları işlemeyi ve başarılı işlem sonrası kullanıcı arayüzünü (UI) güncellemeyi öğreneceğiz. Fetch API veya Axios kütüphanesini kullanmaya devam edeceğiz.
Ön Gereksinim:
- Vue.js temelleri ve bileşen kavramı anlaşılmış olmalı.
- Asenkron JavaScript (Promises, Async/Await) ve Fetch API ile temel API tüketimi konuları anlaşılmış olmalı.
- Vue'da GET API çağrıları (Vue.js ile Web API Çağrıları ve Veri Yönetimi (Fetch veya Axios) konusunda) anlaşılmış olmalı.
- Test için POST, PUT ve DELETE metotlarını destekleyen bir Web API'ye (örneğin Python Flask API'sini Veritabanına Bağlama (SQLAlchemy ile) veya Web API Güvenliği Temelleri (Authentication ve Authorization) konularındaki API) erişiminiz olmalı.
2. Veri Güncelleme API Çağrıları Nasıl Tetiklenir? (@click, @submit.prevent)[/B]
POST, PUT veya DELETE istekleri genellikle bir kullanıcının belirli bir eylemi sonucunda yapılır:
- Bir butona tıklama (örneğin "Sil" butonu, "Güncelle" butonu). Vue şablonunda `@click="metotAdı(veri)"` kullanılır.
- Bir form gönderme (örneğin "Yeni Ürün Ekle" formu). Vue şablonunda `@submit="metotAdı($event)"` kullanılır. Formun standart gönderimini (sayfa yenileme) engellemek için `@submit.prevent="metotAdı"` şeklinde `.prevent` değiştiricisi eklenmelidir.
3. POST İsteği Gönderme (Veri Oluşturma)[/B]
Yeni bir kaynak (örneğin yeni bir ürün) oluşturmak için kullanılır.
- Metot: `'POST'`
- URL: Genellikle kaynağın ait olduğu koleksiyonun adresi (örneğin `/products`).
- Body: Oluşturulacak yeni kaynağın verisi (genellikle JSON formatında bir obje) istek body'sinde gönderilir.
- Headers: `Content-Type: application/json` başlığı, body'de JSON gönderildiğini belirtmelidir. API güvenlik için API anahtarı veya token gerektiriyorsa ilgili başlıklar da eklenmelidir (Web API Güvenliği Temelleri konusundan hatırlayarak).
JavaScript:
// Örnek bir Vue bileşeni metodu içinde
// async function createProduct() { ... }
async createProduct() {
const productNameInput = document.getElementById('new-product-name'); // Varsayılan DOM erişimi veya v-model ile veri alma
const productPriceInput = document.getElementById('new-product-price');
const productName = productNameInput.value;
const productPrice = parseFloat(productPriceInput.value); // Sayıya çevir
const newProductData = { ad: productName, fiyat: productPrice }; // Gönderilecek veri objesi
const apiKey = 'admin_super_key'; // API Key (gerçek uygulamada daha güvenli yönetilir)
try {
// --- Fetch API ile POST ---
// const response = await fetch(API_URL + '/products', {
// method: 'POST',
// headers: {
// 'Content-Type': 'application/json',
// 'X-API-Key': apiKey
// },
// body: JSON.stringify(newProductData) // JS objesini JSON string'e çevir
// });
// --- Axios ile POST ---
const response = await axios.post(API_URL + '/products', newProductData, { // Axios body'yi otomatik JSON'a çevirir
headers: {
'X-API-Key': apiKey // Başlıkları ekle
}
});
if (!response.ok && !response.data) { // Fetch veya Axios yanıt kontrolü (duruma göre değişir)
// Hata yönetimi (Konu 26)
const errorDetails = response.data || await response.json(); // Axios'ta response.data, Fetch'te response.json()
throw new Error(`API Hatası! Status: ${response.status}, Mesaj: ${errorDetails.message || response.statusText}`);
}
// Başarılı yanıt (201 Created veya 200 OK yaygın)
console.log('Ürün Ekleme Başarılı:', response.data); // Axios: response.data, Fetch: await response.json() sonrası data
alert('Ürün başarıyla eklendi!');
// Formu temizle
productNameInput.value = '';
productPriceInput.value = '';
// UI'ı güncelle: Listeyi yeniden çek (en basit yöntem)
this.fetchProducts(); // Ürün listesini yeniden çek metodu (Konu 30'dan)
} catch (error) {
console.error('Ürün ekleme sırasında hata oluştu:', error);
alert('Ürün eklenirken hata oluştu: ' + error.message);
}
}
4. PUT İsteği Gönderme (Veri Güncelleme)[/B]
Mevcut bir kaynağı (belirli bir ID'ye sahip ürünü) güncellemek için kullanılır.
- Metot: `'PUT'`
- URL: Güncellenecek kaynağın adresi (örneğin `/products/ID_NUMARASI`).
- Body: Güncel veriler (JSON obje) istek body'sinde gönderilir. Genellikle güncellenmeyecek alanlar da dahil olmak üzere kaynağın tam hali gönderilir, ancak sadece değişen alanları gönderen PATCH metodu da vardır.
- Headers: `Content-Type: application/json`, Authentication headers.
JavaScript:
// Bir ürün objesini güncelleyen metot (örneğin bir formdan veya modal pencereden tetiklenir)
async updateProduct(product) { // Güncellenecek ürün objesi (ID dahil) argüman olarak gelir
const updatedProductData = { // Güncellenmiş veri (formdan veya inputlardan alınmış)
ad: product.ad, // Örnek: Ürün objesindeki ad ve fiyatı güncellenmiş varsayalım
fiyat: product.fiyat
// Belki başka alanlar
};
const apiKey = 'admin_super_key'; // API Key
try {
// --- Fetch API ile PUT ---
// const response = await fetch(`${API_URL}/products/${product.id}`, { // URL'de ID olmalı
// method: 'PUT',
// headers: {
// 'Content-Type': 'application/json',
// 'X-API-Key': apiKey
// },
// body: JSON.stringify(updatedProductData)
// });
// --- Axios ile PUT ---
const response = await axios.put(`${API_URL}/products/${product.id}`, updatedProductData, {
headers: {
'X-API-Key': apiKey
}
});
if (!response.ok && !response.data) { // Fetch veya Axios yanıt kontrolü
const errorDetails = response.data || await response.json();
throw new Error(`API Hatası! Status: ${response.status}, Mesaj: ${errorDetails.message || response.statusText}`);
}
// Başarılı yanıt (genellikle 200 OK)
console.log('Ürün Güncelleme Başarılı:', response.data);
alert('Ürün başarıyla güncellendi!');
// UI'ı güncelle: Listeyi yeniden çek
this.fetchProducts();
} catch (error) {
console.error('Ürün güncelleme sırasında hata oluştu:', error);
alert('Ürün güncellenirken hata oluştu: ' + error.message);
}
}
5. DELETE İsteği Gönderme (Veri Silme)[/B]
Mevcut bir kaynağı silmek için kullanılır.
- Metot: `'DELETE'`
- URL: Silinecek kaynağın adresi (örneğin `/products/ID_NUMARASI`).
- Body: Genellikle boş bırakılır.
- Headers: Authentication headers.
JavaScript:
// Bir ürünü silen metot (örneğin bir sil butonuna bağlı)
async deleteProduct(productId) { // Silinecek ürünün ID'si argüman olarak gelir
const apiKey = 'admin_super_key'; // API Key
// Kullanıcıdan silme onayı alma (isteğe bağlı ama önerilir)
if (!confirm('Bu ürünü silmek istediğinizden emin misiniz?')) {
return; // Kullanıcı iptal ettiyse işlemi durdur
}
try {
// --- Fetch API ile DELETE ---
// const response = await fetch(`${API_URL}/products/${productId}`, {
// method: 'DELETE',
// headers: {
// 'X-API-Key': apiKey
// }
// // DELETE isteğinde body genellikle gönderilmez
// });
// --- Axios ile DELETE ---
const response = await axios.delete(`${API_URL}/products/${productId}`, {
headers: {
'X-API-Key': apiKey
}
// DELETE isteğinde body genellikle gönderilmez, gerekirse config objesine 'data' olarak eklenebilir
});
if (!response.ok && !response.data) { // Fetch veya Axios yanıt kontrolü
const errorDetails = response.data || await response.json();
throw new Error(`API Hatası! Status: ${response.status}, Mesaj: ${errorDetails.message || response.statusText}`);
}
// Başarılı yanıt (genellikle 200 OK)
console.log('Ürün Silme Başarılı:', response.data); // Genellikle silme mesajı döner
alert('Ürün başarıyla silindi!');
// UI'ı güncelle: Listeyi yeniden çek (en basit yöntem)
this.fetchProducts(); // Ürün listesini yeniden çek metodu
// Veya daha performanslı: Silinen ürünü yerel listeden çıkar
// this.urunler = this.urunler.filter(urun => urun.id !== productId);
} catch (error) {
console.error('Ürün silme sırasında hata oluştu:', error);
alert('Ürün silinirken hata oluştu: ' + error.message);
}
}
6. Tam Bir CRUD API Tüketimi Örneği (GET, POST, DELETE Basit)[/B]
Aşağıdaki örnek kod, Vue.js ile Web API Çağrıları ve Veri Yönetimi (Fetch veya Axios) konusundaki ürün listeleme bileşenine, basit bir ekleme formu ve silme butonları ekleyerek POST ve DELETE işlemlerini entegre eder. PUT işlemi benzer mantıkla yapılır.
HTML:
<template> {# SFC template kısmı #}
<div class="product-manager-container">
<h2>Ürün Yönetimi</h2>
{# Yeni Ürün Ekleme Formu #}
<div class="add-product-form">
<h3>Yeni Ürün Ekle</h3>
{# @submit.prevent ile formun standart gönderimini engelle #}
<form @submit.prevent="createProduct">
<input type="text" v-model="newProduct.ad" placeholder="Ürün Adı" required> {# v-model ile iki yönlü bağlama #}
<input type="number" v-model="newProduct.fiyat" placeholder="Fiyat" step="0.01" required>
<button type="submit">Ekle</button>
</form>
<p v-if="formError" style="color: red;">{{ formError }}</p> {# Form hata mesajı #}
</div>
<hr>
{# Yüklenme ve Hata Durumları #}
<p v-if="yukleniyor">Ürünler yükleniyor...</p>
<p v-else-if="hata" class="error-message">Ürünler yüklenemedi: {{ hata.message }}</p>
{# Ürün Listesi (Veri Başarıyla Yüklendiğinde) #}
<ul v-else-if="urunler && urunler.length > 0">
<li v-for="urun in urunler" :key="urun.id">
{{ urun.ad }} - {{ urun.fiyat }} TL (ID: {{ urun.id }})
{# Silme butonu - Tıklaninca deleteProduct metodunu çağır, urun.id'yi argüman gönder #}
<button @click="deleteProduct(urun.id)">Sil</button>
{# Güncelleme butonu - Tıklaninca updateProduct metodunu çağır (örnek olarak) #}
{# <button @click="updateProduct(urun)">Güncelle</button> #}
</li>
</ul>
{# Liste boşsa mesaj #}
<p v-else>Henüz görüntülenecek ürün bulunamadı.</p>
</div>
</template>
<script> {# SFC script kısmı #}
import axios from 'axios'; // Axios kullanıyorsanız içe aktarın
const API_URL = 'http://127.0.0.1:5000/products'; // API endpoint'i
const API_KEY = 'admin_super_key'; // API Key (gerçek uygulamada daha güvenli yönetilir)
export default {
data() {
return {
urunler: [],
yukleniyor: true,
hata: null,
// Yeni ürün formu için veri
newProduct: { ad: '', fiyat: null }, // v-model ile bağlı
formError: null // Form hataları için
};
},
mounted() {
console.log('Bileşen DOM\'a eklendi, ilk veri çekiliyor.');
this.fetchProducts(); // Bileşen yüklendiğinde listeyi çek
},
methods: {
// API'den tüm ürünleri çeken metot (Konu 30'dan)
async fetchProducts() {
this.yukleniyor = true;
this.hata = null;
try {
// Axios ile GET isteği
const response = await axios.get(API_URL, {
headers: { 'X-API-Key': API_KEY }
});
this.urunler = response.data; // Axios otomatik JSON parse eder
} catch (error) {
console.error('Ürün listesi çekilirken hata:', error);
if (error.response) {
this.hata = new Error(`API Hatası! Status: ${error.response.status}, Mesaj: ${error.response.data.message || error.message}`);
} else {
this.hata = new Error('Ağ veya istek hatası: ' + error.message);
}
} finally {
this.yukleniyor = false;
}
},
// Yeni ürün ekleme metotu (POST)
async createProduct() {
this.formError = null; // Önceki hataları temizle
// Basit form doğrulaması
if (!this.newProduct.ad || this.newProduct.fiyat === null || this.newProduct.fiyat < 0) {
this.formError = "Lütfen geçerli ürün adı ve fiyat girin.";
return; // İşlemi durdur
}
try {
// Axios ile POST isteği
const response = await axios.post(API_URL, this.newProduct, { // newProduct objesi body'ye gidecek
headers: {
'X-API-Key': API_KEY
// 'Content-Type' axios tarafından otomatik ayarlanır
}
});
if (!response.data) { // Başarılı yanıt body'si boş olabilir
throw new Error(`API yanıt body'si boş veya beklenmiyor. Status: ${response.status}`);
}
console.log('Ürün Ekleme Başarılı:', response.data);
alert('Ürün başarıyla eklendi!');
// Formu temizle
this.newProduct = { ad: '', fiyat: null };
// Listeyi yeniden çekerek UI'ı güncelle
this.fetchProducts();
} catch (error) {
console.error('Ürün ekleme sırasında hata:', error);
if (error.response) {
this.formError = `API Hatası! Status: ${error.response.status}, Mesaj: ${error.response.data.message || error.message}`;
} else {
this.formError = 'Ağ veya istek hatası: ' + error.message;
}
alert('Ürün eklenirken hata oluştu.');
}
},
// Ürün silme metotu (DELETE)
async deleteProduct(productId) { // Silinecek ürünün ID'si argüman olarak gelir
// Kullanıcıdan silme onayı (opsiyonel)
if (!confirm('Bu ürünü silmek istediğinizden emin misiniz?')) {
return;
}
try {
// Axios ile DELETE isteği
const response = await axios.delete(`${API_URL}/${productId}`, { // URL'de ID olmalı
headers: { 'X-API-Key': API_KEY }
});
if (!response.data) { // Başarılı yanıt body'si boş olabilir
throw new Error(`API yanıt body'si boş veya beklenmiyor. Status: ${response.status}`);
}
console.log('Ürün Silme Başarılı:', response.data);
alert('Ürün başarıyla silindi!');
// Listeyi yeniden çekerek UI'ı güncelle
this.fetchProducts();
// Veya silinen elemanı doğrudan yerel listeden çıkararak (daha performanslı)
// this.urunler = this.urunler.filter(urun => urun.id !== productId);
} catch (error) {
console.error('Ürün silme sırasında hata:', error);
if (error.response) {
alert(`Hata! Status: ${error.response.status}, Mesaj: ${error.response.data.message || error.message}`);
} else {
alert('Ağ veya istek hatası: ' + error.message);
}
}
},
// Güncelleme metotu (PUT) - POST'a benzer, URL'de ID olur
// async updateProduct(product) { ... } // Benzer mantıkla yazılabilir
}
};
</script>
<style scoped> {# SFC style kısmı #}
.error-message { color: red; font-weight: bold;}
.add-product-form input { margin-right: 5px; padding: 5px;}
button { cursor: pointer; margin-right: 5px; }
</style>
Sıra Sizde![/B]
Vue.js ile API'ye veri gönderen (POST, PUT, DELETE) interaktif arayüzler oluşturmayı gördük.
- Vue projenizde, Vue.js ile Web API Çağrıları ve Veri Yönetimi (Fetch veya Axios) konusundaki bileşeninizi açın veya yeni bir bileşen oluşturun.
- `<template>` kısmına yeni ürün ekleme formu ve ürünleri listelediğiniz `<li>`'lerin yanına bir "Sil" butonu ekleyin.
- Bileşeninizin `data()` kısmına form verileri için (`newProduct` gibi) reaktif değişkenler ekleyin (v-model kullanıyorsanız).
- `@submit.prevent` ile formun submit olayını, `@click` ile silme butonunu ilgili metotlara (`createProduct`, `deleteProduct`) bağlayın.
- `methods` objesine `async createProduct()` ve `async deleteProduct(productId)` metotlarını ekleyin.
- Bu metotların içinde, Axios veya Fetch kullanarak çalışan API'nizin POST ve DELETE endpoint'lerine istekler gönderin. Body'ye form verilerini (POST için), URL'ye ID'yi (DELETE için) ekleyin. API Key gibi başlıkları eklemeyi unutmayın.
- `try...catch` blokları ile hata yönetimini yapın.
- Başarılı POST veya DELETE işlemi sonrası `this.fetchProducts()` metodunu çağırarak ürün listesini yeniden yükleyin ve UI'ı güncelleyin.
- Tarayıcınızda uygulamayı test edin: Yeni ürün ekleyin, eklenen ürünü silin. İşlemlerin başarılı olduğunu ve listenin güncellendiğini doğrulayın. API test araçlarıyla da (Postman/Insomnia/curl) API'nin hala doğru çalıştığını kontrol edin.
- Güncelleme (PUT) işlemi için de benzer mantıkla bir metot yazmayı deneyin (formdan güncel veri alıp, URL'de ID ile PUT isteği gönderme).
Serinin Geleceği?[/B]
Vue.js ile API'ye veri göndererek (POST, PUT, DELETE) interaktif CRUD arayüzleri oluşturma konusunda önemli bir adım attık. Bu, dinamik web uygulamaları için temeldir.
Seriyi buradan sonra nasıl devam ettirelim?
- Vue Router'da daha ileri konular (Route parametreleri ile belirli bir ürünü düzenleme sayfası açma, Navigation Guards)?
- Vuex veya Pinia ile Merkezi State Management (API'den çekilen veya paylaşılan verileri daha yönetilebilir hale getirme)?
- API çağrılarında daha ileri konular (Axios interceptors, merkezi API servisleri, daha detaylı hata yönetimi)?
- Vue bileşenlerinde daha ileri konular (Slotlar, Dinamik Bileşenler, Teleport)?
- Başka bir programlama diline giriş (C#, C++ gibi)?
- Veya başka önerileriniz mi var?
Umarım bu konu, veri yönetimi yapabilen web arayüzleri geliştirmeye başlarken faydalı olmuştur. Görüşmek üzere!
Bu konu, "Hazır Kod Bankası" serisinin otuz birinci parçasıdır ve "Yazılım Bilgi ve Yeni Başlayanlar İçin" kategorisi altında paylaşılmıştır.