Çevrimdışı sorunsuz çalışan uygulamalar oluşturmak, modern web geliştiriciliğinde önemli bir gereklilik haline geldi. IndexedDB, tarayıcıda doğrudan büyük miktarda veri depolamak ve yönetmek isteyen geliştiriciler için güçlü bir çözüm sunar. Bu istemci tarafı NoSQL veritabanı, verilerin verimli bir şekilde işlenmesini sağlar ve bu da onu çevrimdışı işlevselliğe ihtiyaç duyan web uygulamaları için ideal hale getirir. Bu makalede, IndexedDB'nin temellerini, temel özelliklerini inceleyeceğiz ve web projelerinizde nasıl kurup kullanacağınızın adımlarını size göstereceğiz.
IndexedDB Nedir?
IndexedDB , web uygulamalarının yapılandırılmış verileri doğrudan tarayıcıda depolamasını ve yönetmesini sağlayan güçlü bir istemci tarafı NoSQL veritabanıdır. Büyük veri kümelerini yerel olarak işlemek için verimli bir çözüm sunar ve bu da onu çevrimdışı işlevsellik ve veri yoğun uygulamalar için ideal hale getirir.

IndexedDB'nin temel avantajlarından biri, çevrimdışı web uygulamalarını destekleme yeteneğidir. Geliştiricilerin önemli miktarda veri depolamasına, hızlı alma için indeksleme kullanmasına, işlemleri yönetmesine ve imleçler kullanarak verilerde gezinmesine olanak tanır. Bu özellikler, onu web uygulamalarında karmaşık verileri işlemek için mükemmel bir seçim haline getirir.
Chrome, Firefox, Safari ve Edge dahil olmak üzere çoğu modern web tarayıcısı IndexedDB'yi destekler. Ancak, web uygulamanız için hedeflediğiniz tarayıcıyla IndexedDB sürümünün uyumlu olduğundan emin olmak önemlidir.
IndexedDB'yi kullanmaya başlamak için ilk adım, veritabanına bir bağlantı açmaktır; bu, onu oluşturmak ve etkileşimde bulunmak için gereklidir.

IndexedDB'ye Başlarken: Kapsamlı Bir Kılavuz
IndexedDB, web uygulamaları için güçlü bir istemci tarafı depolama çözümüdür. Bu kılavuz, temel kurulumdan gelişmiş tekniklere ve gerçek dünya uygulamasına kadar her şeyi size gösterecektir.
IndexedDB'yi Kurma
Veritabanı Oluşturma ve Açma
IndexedDB'de yeni bir veritabanı oluşturmak için indexedDB.open()
yöntemini kullanacaksınız:
const request = indexedDB.open("MyDatabase", 1);
request.onupgradeneeded = (event) => {
const db = event.target.result;
// Create object stores and indexes here
};
Yöntem iki parametre alır: veritabanı adı ve sürüm numarası. Mevcut bir veritabanını açmak için, bir sürüm numarası belirtmeden yöntemi çağırmanız yeterlidir.
Veritabanı Sürümlendirmesi
IndexedDB, şema değişikliklerini işlemek için sürümlendirmeyi destekler. Bir veritabanını mevcut olandan daha yüksek bir sürüm numarasıyla açtığınızda, onupgradeneeded
olayı tetiklenir ve veritabanı şemanızı güncellemenize olanak tanır.
Nesne Mağazaları ve Dizinler Oluşturma
Nesne mağazaları, IndexedDB'deki verileriniz için kapsayıcılardır:
request.onupgradeneeded = (event) => {
const db = event.target.result;
// Create an object store with a key path
const objectStore = db.createObjectStore("customers", { keyPath: "id" });
// Create an index for efficient querying
objectStore.createIndex("name", "name", { unique: false });
};
İşlemlerle Çalışma
İşlem Temellerini Anlama
IndexedDB'deki işlemler, birden fazla işlemi tek, atomik bir birimde gruplandırarak veri bütünlüğünü korur. Ya tüm değişikliklerin uygulanmasını ya da hiçbirinin uygulanmamasını sağlarlar.
İşlemler Oluşturma ve Yönetme
const transaction = db.transaction(["customers"], "readwrite");
const objectStore = transaction.objectStore("customers");
transaction.oncomplete = (event) => {
console.log("Transaction completed successfully");
};
transaction.onerror = (event) => {
console.error("Transaction failed");
};
Hata İşleme ve Geri Alma
Bir işlem başarısız olursa, tüm işlemi geri almak için abort()
yöntemini kullanabilirsiniz:
try {
// Perform operations
} catch (error) {
transaction.abort();
console.error("Transaction aborted:", error);
}
IndexedDB'de Veri İşlemleri
Veri Ekleme
const customerData = { id: "00001", name: "John Doe", email: "john@example.com" };
const request = objectStore.add(customerData);
request.onsuccess = (event) => {
console.log("Data added successfully");
};
Veri Alma
Anahtara göre temel veri alma:
const request = objectStore.get("00001");
request.onsuccess = (event) => {
console.log("Customer data:", request.result);
};
Dizinlerle Filtreleme
const index = objectStore.index("name");
const request = index.get("John Doe");
request.onsuccess = (event) => {
console.log("Found by name:", request.result);
};
Gelişmiş Sorgulama Yöntemleri
Karmaşık sorgular için IndexedDB, openCursor()
ve IDBKeyRange
gibi yöntemleri kullanarak aralık sorguları ve bileşik sorgular sunar:
const range = IDBKeyRange.bound("A", "F"); // Names starting with A through F
const request = index.openCursor(range);
Kayıtları Güncelleme
const updateData = { id: "00001", name: "John Smith", email: "john@example.com" };
const request = objectStore.put(updateData);
Kayıtları Silme
const request = objectStore.delete("00001");
request.onsuccess = (event) => {
console.log("Record deleted");
};
İmleçlerle Çalışma
İmleç İşlevselliğini Anlama
İmleçler, bir nesne deposundaki veya dizindeki kayıtlar üzerinde verimli bir şekilde yineleme yapmanıza, veri üzerinde gezinme ve veri işleme yolu sağlar.
Kayıtlarda Gezinme
const request = objectStore.openCursor();
request.onsuccess = (event) => {
const cursor = event.target.result;
if (cursor) {
console.log("Key:", cursor.key, "Value:", cursor.value);
cursor.continue(); // Move to the next record
} else {
console.log("No more records");
}
};
İmleçleri Kullanarak Verileri Değiştirme
const transaction = db.transaction(["customers"], "readwrite");
const objectStore = transaction.objectStore("customers");
const request = objectStore.openCursor();
request.onsuccess = (event) => {
const cursor = event.target.result;
if (cursor) {
if (cursor.value.status === "inactive") {
const updateData = cursor.value;
updateData.status = "active";
cursor.update(updateData);
}
cursor.continue();
}
};
Şema Yönetimi ve Yükseltmeler
Veritabanı Şemasını Yükseltme
Uygulamanız geliştikçe, veritabanı şemanızı değiştirmeniz gerekebilir:
const request = indexedDB.open("MyDatabase", 2); // Increase version number
request.onupgradeneeded = (event) => {
const db = event.target.result;
// Check if the object store exists
if (!db.objectStoreNames.contains("newStore")) {
db.createObjectStore("newStore", { keyPath: "id" });
}
};
Yükseltmeler Sırasında Veri Geçirme
request.onupgradeneeded = (event) => {
const db = event.target.result;
const oldVersion = event.oldVersion;
if (oldVersion < 1) {
// First version setup
}
if (oldVersion < 2) {
// Migrate data to new schema
const transaction = event.target.transaction;
const oldStore = transaction.objectStore("oldStore");
const newStore = db.createObjectStore("newStore", { keyPath: "id" });
oldStore.openCursor().onsuccess = (event) => {
const cursor = event.target.result;
if (cursor) {
newStore.add(cursor.value);
cursor.continue();
}
};
}
};
Performans Optimizasyonu
Verimli Toplu İşlemler
Daha iyi performans için, birden fazla kayıtla uğraşırken toplu işlemleri kullanın:
const transaction = db.transaction(["customers"], "readwrite");
const store = transaction.objectStore("customers");
// Add multiple records in a single transaction
customerList.forEach(customer => {
store.add(customer);
});
Daha Hızlı Sorgular İçin Dizinlerden Yararlanma
Daha hızlı veri alımı sağlamak için sık sorgulanan özellikler üzerinde dizinler oluşturun:
objectStore.createIndex("email", "email", { unique: true });
objectStore.createIndex("lastLogin", "lastLogin", { unique: false });
Bağlantı Yönetimi En İyi Uygulamaları
Yalnızca gerektiğinde bağlantıları açın ve işiniz bittiğinde kapatın:
let db;
function openDB() {
const request = indexedDB.open("MyDatabase", 1);
request.onsuccess = (event) => {
db = event.target.result;
};
return request;
}
// When you're done with the database
function closeDB() {
if (db) {
db.close();
db = null;
}
}
Gerçek Dünya Örneği: Çevrimdışı Destekli Görev Yöneticisi
Veritabanı Kurulumu
const request = indexedDB.open("TaskManagerDB", 1);
request.onupgradeneeded = (event) => {
const db = event.target.result;
const taskStore = db.createObjectStore("tasks", { keyPath: "id", autoIncrement: true });
// Create indexes for querying
taskStore.createIndex("status", "status", { unique: false });
taskStore.createIndex("dueDate", "dueDate", { unique: false });
};
Görev Ekleme
function addTask(taskData) {
const transaction = db.transaction(["tasks"], "readwrite");
const taskStore = transaction.objectStore("tasks");
return new Promise((resolve, reject) => {
const request = taskStore.add({
title: taskData.title,
description: taskData.description,
status: "pending",
dueDate: taskData.dueDate,
createdAt: new Date()
});
request.onsuccess = () => resolve(request.result);
request.onerror = () => reject(request.error);
});
}
Görevleri Alma ve Görüntüleme
function getAllTasks() {
const transaction = db.transaction(["tasks"], "readonly");
const taskStore = transaction.objectStore("tasks");
return new Promise((resolve, reject) => {
const request = taskStore.openCursor();
const tasks = [];
request.onsuccess = (event) => {
const cursor = event.target.result;
if (cursor) {
tasks.push(cursor.value);
cursor.continue();
} else {
resolve(tasks);
}
};
request.onerror = () => reject(request.error);
});
}
Görevleri Güncelleme ve Silme
function updateTaskStatus(id, newStatus) {
const transaction = db.transaction(["tasks"], "readwrite");
const taskStore = transaction.objectStore("tasks");
return new Promise((resolve, reject) => {
const getRequest = taskStore.get(id);
getRequest.onsuccess = () => {
const task = getRequest.result;
task.status = newStatus;
task.updatedAt = new Date();
const updateRequest = taskStore.put(task);
updateRequest.onsuccess = () => resolve(true);
updateRequest.onerror = () => reject(updateRequest.error);
};
getRequest.onerror = () => reject(getRequest.error);
});
}
Sunucuyla Senkronizasyon
function syncWithServer() {
if (!navigator.onLine) {
return Promise.reject(new Error("No internet connection"));
}
return getAllTasks()
.then(tasks => {
// Filter tasks that need syncing
const unsynced = tasks.filter(task => !task.synced);
// Send to server using fetch API
return fetch('https://api.example.com/tasks/sync', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(unsynced)
});
})
.then(response => response.json())
.then(result => {
// Mark tasks as synced
const transaction = db.transaction(["tasks"], "readwrite");
const taskStore = transaction.objectStore("tasks");
result.syncedIds.forEach(id => {
const request = taskStore.get(id);
request.onsuccess = () => {
const task = request.result;
task.synced = true;
taskStore.put(task);
};
});
return result;
});
}
// Listen for online events to sync automatically
window.addEventListener('online', syncWithServer);
API Yönetimi için Apidog'u IndexedDB ile Entegre Etme
İstemci tarafı depolama için IndexedDB ile uygulamalar oluştururken, genellikle veri senkronizasyonu için arka uç API'leriyle etkileşim kurmanız gerekir. Apidog, bu API etkileşimlerini yönetmek için sorunsuz bir çözüm sunar.

Apidog'un IndexedDB Geliştirmeyi Neden İyileştirdiği
IndexedDB ile çevrimdışı özellikli uygulamalar geliştirirken, Apidog çeşitli avantajlar sunar:
Gerçek Zamanlı Senkronizasyon: Apidog, veri senkronizasyonu için kullanılan API uç noktalarınızın her zaman düzgün bir şekilde yapılandırılmasını ve test edilmesini sağlar, böylece uygulamanız çevrimiçi olduğunda entegrasyon sorunlarını ortadan kaldırır.
Sahte API Yanıtları: Çevrimdışı işlevsellik geliştirirken, Apidog'un akıllı sahte motorları, canlı bir sunucu olmadan IndexedDB senkronizasyon mantığınızı test etmek için API yanıtlarını simüle etmenize olanak tanır.

İşbirlikçi API Tasarımı: Ekibiniz aynı anda ön uç depolama ve arka uç API'leri üzerinde çalışırken, Apidog API spesifikasyonları üzerinde gerçek zamanlı işbirliğini kolaylaştırır.

Apidog'u geliştirme iş akışınıza entegre ederek, istemci tarafı depolama ile sunucu tarafı işleme arasında sorunsuz bir köprü oluşturur, uygulamanızı daha sağlam ve bakımı daha kolay hale getirirsiniz.