Veri yönetimi, modern yazılım geliştirmenin temel taşlarından biridir ve bu süreç, genellikle karmaşık ve hataya açık olabilir. Uygulamanızın veri katmanını daha düzenli, test edilebilir ve sürdürülebilir hale getirmek ister misiniz? Bu kapsamlı rehber, Mitsuki Repositories ile tanışarak sıfırdan başlayıp, tam kapsamlı CRUD (Create, Read, Update, Delete) operasyonlarını adım adım nasıl yöneteceğinizi gösterecek.
Modern yazılım mimarilerinde veri yönetimi, uygulamanın en kritik bileşenlerinden biridir. Veritabanı ile doğrudan etkileşim kurmak, özellikle büyük ve karmaşık projelerde zamanla sürdürülemez bir hal alabilir. İşte tam bu noktada, Repository Pattern (Depo Deseni) devreye girer. Mitsuki Repositories, bu deseni uygulayan, veri erişim katmanınızı soyutlayan ve iş mantığınızı veritabanı detaylarından ayıran kurgusal bir kütüphanedir. Basitçe ifade etmek gerekirse, Mitsuki, uygulamanızın veritabanı ile nasıl konuştuğunu standartlaştıran, temiz ve düzenli bir arayüz sunar. Bu sayede, geliştiriciler veritabanı sorgularının detaylarıyla uğraşmak yerine, iş kurallarına odaklanabilirler.
Peki, Mitsuki Repositories’i kullanmak neden bu kadar önemli? Temel faydaları birkaç ana başlık altında toplayabiliriz:
- Soyutlama (Abstraction): Mitsuki, uygulamanız ile veritabanı arasında bir soyutlama katmanı oluşturur. Bu, kullandığınız veritabanı teknolojisini (SQL, NoSQL, in-memory) değiştirmek istediğinizde, iş mantığınızda minimum değişiklik yapmanız gerektiği anlamına gelir. Uygulamanız, veritabanının MySQL mi, PostgreSQL mi yoksa MongoDB mi olduğunu bilmek zorunda kalmaz. Sadece Mitsuki Repository’nin sunduğu arayüzle etkileşime geçer.
- Sürdürülebilirlik ve Bakım Kolaylığı: Tüm veri erişim mantığı tek bir yerde toplandığı için kodunuz daha düzenli hale gelir. Bir hata ayıklama veya yeni bir özellik ekleme gerektiğinde, ilgili veri operasyonlarını kolayca bulabilir ve güncelleyebilirsiniz. Bu, uzun vadede projenin bakım maliyetlerini önemli ölçüde düşürür.
- Test Edilebilirlik: Repository deseni, test yazımını büyük ölçüde kolaylaştırır. Veritabanına bağımlı olan iş mantığınızı test etmek istediğinizde, gerçek veritabanı yerine Mitsuki Repository’nin “mock” (sahte) bir uygulamasını kullanabilirsiniz. Bu, testlerin daha hızlı çalışmasını sağlar ve dış bağımlılıkları ortadan kaldırarak daha güvenilir test sonuçları elde etmenize yardımcı olur.
Uzman İpucu: Unit test yazarken repository’leri soyutlamak, testlerinizi %60 daha hızlı ve bağımsız hale getirebilir.
- Bağımlılık Enjeksiyonu (Dependency Injection): Mitsuki Repositories, bağımlılık enjeksiyonu prensiplerine uygun olarak tasarlanmıştır. Bu, bir kontrolcünün veya bir servis katmanının doğrudan bir veritabanı bağlantısı oluşturmak yerine, ihtiyacı olan repository’i dışarıdan almasını sağlar. Bu sayede, bileşenleriniz daha az bağımlı ve daha esnek hale gelir.
- Tutarlılık: Veri erişim desenleri ve isimlendirme kuralları Mitsuki tarafından standartlaştırıldığı için, farklı geliştiricilerin yazdığı kodlar arasında tutarlılık sağlanır. Bu, ekip çalışmasında önemli bir avantaj sunar.
Kısacası, Mitsuki Repositories kullanmak, veri katmanınızı modern, esnek ve ölçeklenebilir bir yapıya kavuşturmanın anahtarıdır. Bu sayede uygulamanız, gelecekteki değişikliklere ve genişlemelere karşı çok daha dirençli hale gelir. Veritabanı etkileşimlerinin karmaşıklığını bir kenara bırakıp, uygulama iş mantığınıza odaklanmak istiyorsanız, Mitsuki Repositories tam size göre bir çözüm sunar. Bir sonraki bölümde, bu güçlü yapıyı projenize nasıl entegre edeceğinizi adım adım inceleyeceğiz.
Mitsuki ile Geliştirme Ortamı Nasıl Kurulur ve İlk Repository Adımları Nelerdir?
Mitsuki Repositories ile çalışmaya başlamak için öncelikle basit bir geliştirme ortamı kurmamız gerekiyor. Bu bölümde, Node.js ve NPM (Node Package Manager) kullanarak bir proje oluşturacak ve Mitsuki’nin temel yapılandırmasını yapacağız. Amacımız, sıfırdan bir “Görev Yöneticisi” uygulaması için veri erişim katmanını oluşturmak ve ilk repository’mizi hayata geçirmektir.
1. Gerekli Araçların Kurulumu:
Öncelikle bilgisayarınızda Node.js ve NPM’in kurulu olduğundan emin olun. Eğer kurulu değilse, Node.js’in resmi web sitesinden indirebilirsiniz. Kurulum tamamlandıktan sonra terminalinizde aşağıdaki komutları çalıştırarak versiyonlarını kontrol edebilirsiniz:
node -v
npm -v
2. Proje Başlatma:
Yeni bir proje klasörü oluşturun ve terminalde bu klasöre gidin:
mkdir mitsuki-gorev-yoneticisi
cd mitsuki-gorev-yoneticisi
npm init -y
npm init -y komutu, varsayılan ayarlarla bir package.json dosyası oluşturacaktır.
3. Mitsuki ve Yardımcı Paketlerin Kurulumu:
Mitsuki'yi ve bir veritabanı adaptörünü (bu örnekte SQLite kullanacağız, ancak konsept diğer veritabanları için de benzerdir) projemize ekleyelim:
npm install mitsuki-repo sqlite3
Burada mitsuki-repo, bizim kurgusal Mitsuki Repository kütüphanemizdir ve sqlite3 ise veritabanı bağlantısı için bir adaptördür.
4. Mitsuki Yapılandırması:
Proje kök dizininde config.js adında bir dosya oluşturalım. Bu dosya, Mitsuki'nin veritabanı bağlantı ayarlarını içerecektir:
// config.js
module.exports = {
database: {
client: 'sqlite3',
connection: {
filename: './dev.sqlite3' // Veritabanı dosyasının yolu
},
useNullAsDefault: true // SQLite için önerilen ayar
}
};
Bu yapılandırma, Mitsuki'ye SQLite veritabanı kullanacağını ve veritabanı dosyasının dev.sqlite3 adıyla proje klasöründe bulunacağını söyler.
5. İlk Model Tanımı:
Mitsuki, veritabanı tablolarınızı temsil eden modellere ihtiyaç duyar. models adında bir klasör oluşturalım ve içine Task.js adında bir dosya ekleyelim:
// models/Task.js
const { Model } = require('mitsuki-repo');
class Task extends Model {
static get tableName() {
return 'tasks'; // Bu modelin eşleştiği veritabanı tablosu
}
static get jsonSchema() {
return {
type: 'object',
required: ['title', 'status'],
properties: {
id: { type: 'integer' },
title: { type: 'string', minLength: 3, maxLength: 255 },
description: { type: 'string', maxLength: 1000 },
status: { type: 'string', enum: ['pending', 'completed'], default: 'pending' },
createdAt: { type: 'string', format: 'date-time' },
updatedAt: { type: 'string', format: 'date-time' }
}
};
}
}
module.exports = Task;
Bu kod bloğu, Task adında bir model tanımlar. tableName özelliği, modelin hangi veritabanı tablosuyla eşleştiğini belirtir. jsonSchema ise, bu model için temel veri doğrulama kurallarını ve alan türlerini tanımlar. Bu şema, verilerinizi veritabanına kaydetmeden önce doğrulamanıza yardımcı olur.
Vaka Analizi 1: Görev Yöneticisi için Çekirdek Yapı
Yukarıdaki adımlarla, basit bir görev yöneticisi uygulaması için temel veri modelini ve Mitsuki yapılandırmasını tamamladık. Şimdi, bu yapıyı kullanarak görevleri oluşturmak, okumak, güncellemek ve silmek için repository mantığını nasıl kuracağımızı bir sonraki bölümlerde detaylandıracağız. Örneğin, Task modeli üzerinden yeni görevler ekleyebilecek, mevcut görevleri listeleyebilecek veya durumlarını güncelleyebileceğiz. Bu başlangıç, tüm CRUD operasyonlarının temelini oluşturmaktadır ve uygulamamızın veri katmanını sağlam bir şekilde inşa etmemizi sağlayacaktır.
Şimdiye kadar yaptığımız kurulum ile, veritabanı bağlantısı ve model tanımlaması hazır hale geldi. Bu sayede, iş mantığımızı doğrudan veritabanı işlemleriyle karıştırmadan, temiz bir arayüz üzerinden veri manipülasyonu yapabileceğiz.
Temel CRUD Operasyonları: Mitsuki ile Veri Yaratma (Create) ve Okuma (Read) İşlemleri Nasıl Yapılır?
Mitsuki Repositories'in en temel ve en sık kullanılan işlevleri, veritabanına yeni kayıtlar eklemek (Create) ve mevcut kayıtları sorgulamak (Read) üzerinedir. Bu bölümde, görev yöneticisi uygulamamız üzerinden bu iki kritik operasyonu adım adım inceleyeceğiz. Her operasyon için kod örnekleri ve gerçek dünya senaryoları ile konuyu pekiştireceğiz.
Yeni Kayıt Oluşturma: create Metodu ile Veritabanına Ekleme
Yeni bir görev kaydı oluşturmak, uygulamanızın en sık gerçekleştireceği işlemlerden biridir. Mitsuki, modeliniz üzerinden create metodunu kullanarak bu işlemi son derece basit ve güvenli bir şekilde yapmanızı sağlar. Veri oluştururken, daha önce tanımladığımız jsonSchema devreye girer ve verilerin doğruluğunu otomatik olarak kontrol eder, böylece veritabanına hatalı veri girişini engelleriz.
Öncelikle, Mitsuki'yi yapılandırdığımız ana betik dosyamıza (örneğin, app.js veya index.js) modelimizi ve yapılandırmamızı dahil etmemiz gerekiyor:
// index.js
const { knex } = require('mitsuki-repo');
const config = require('./config');
const Task = require('./models/Task');
// Mitsuki'yi veritabanı konfigürasyonu ile başlat
Task.knex(knex(config.database));
async function main() {
// Veritabanı tablosunu oluştur (eğer yoksa)
// Bu, üretim ortamında migration'lar ile yapılır. Geliştirme için basitleştirildi.
await knex(config.database).schema.createTableIfNotExists('tasks', table => {
table.increments('id').primary();
table.string('title').notNullable();
table.text('description');
table.string('status').defaultTo('pending').notNullable();
table.timestamps(true, true); // createdAt ve updatedAt
});
console.log('Veritabanı tablosu hazır.');
// Yeni bir görev oluşturma örneği
try {
const newTask = await Task.query().insert({
title: 'Mitsuki Rehberini Yaz',
description: 'Zero to Full CRUD teknik makalesini tamamla.',
status: 'pending'
});
console.log('Yeni görev başarıyla eklendi:', newTask.toJSON());
const anotherTask = await Task.query().insert({
title: 'Alışveriş Yap',
description: 'Süpermarketten sebze ve meyve al.',
status: 'pending'
});
console.log('Diğer görev başarıyla eklendi:', anotherTask.toJSON());
} catch (error) {
console.error('Görev eklerken hata oluştu:', error.message);
}
}
main();
Yukarıdaki kodda, Task.query().insert() metodu kullanılarak veritabanına yeni bir görev kaydı eklenir. Mitsuki, bu işlemi veritabanının kendine özgü SQL (veya NoSQL) sorgusuna çevirir. Eğer veritabanı şemasında tanımlı olan title veya status gibi zorunlu alanlar eksik olursa, Mitsuki bir doğrulama hatası fırlatacaktır. Bu, hatalı veri girişlerini daha erken aşamada yakalamak için kritik bir özelliktir.
Kayıtları Okuma: findById, findAll ve Filtreleme Seçenekleri
Veritabanına eklenen kayıtları okumak, bir uygulamanın temel işlevidir. Mitsuki Repositories, farklı senaryolara uygun çeşitli okuma metodları sunar:
- Tekil Kayıt Okuma (
findByIdveyafindOne): Belirli bir ID'ye sahip kaydı veya belirli kriterlere uyan ilk kaydı getirmek için kullanılır. - Çoklu Kayıt Okuma (
findAll,where): Belirli kriterlere uyan birden fazla kaydı veya tüm kayıtları getirmek için kullanılır. Filtreleme, sıralama ve sayfalama gibi seçeneklerle zenginleştirilebilir.
// Devam eden index.js dosyasında
async function readTasks() {
console.log('\n--- Görevleri Okuma İşlemleri ---');
// Tüm görevleri listeleme
const allTasks = await Task.query();
console.log('Tüm görevler:', allTasks.map(task => task.toJSON()));
// Belirli bir ID ile görev bulma
const taskIdToFind = allTasks[0] ? allTasks[0].id : 1;
if (taskIdToFind) {
const taskById = await Task.query().findById(taskIdToFind);
console.log(ID ${taskIdToFind} ile bulunan görev:, taskById ? taskById.toJSON() : 'Bulunamadı.');
}
// Durumu 'pending' olan görevleri filtreleme
const pendingTasks = await Task.query().where('status', 'pending').orderBy('createdAt', 'desc');
console.log('Bekleyen görevler:', pendingTasks.map(task => task.toJSON()));
// Sayfalama (Pagination) örneği: İlk 10 görevi getir
const paginatedTasks = await Task.query().page(0, 10).orderBy('title');
console.log('İlk 10 görev (sayfalı):', paginatedTasks.results.map(task => task.toJSON()), 'Toplam:', paginatedTasks.total);
}
// main fonksiyonunu güncelle
async function main() {
// ... (yukarıdaki kurulum ve insert kodları) ...
await readTasks();
}
main();
Yukarıdaki örnekler, Mitsuki'nin esnek sorgu API'si ile nasıl veri çekebileceğinizi gösterir. where metodu ile belirli koşullar tanımlayabilir, orderBy ile sonuçları sıralayabilir ve page metodu ile sayfalama (pagination) uygulayabilirsiniz. Bu özellikler, büyük veri kümeleriyle çalışırken performans ve kullanıcı deneyimi açısından hayati öneme sahiptir.
Vaka Analizi 2: Görevleri Durumlarına Göre Filtreleyerek Bir UI'da Listeleme
Bir web uygulaması geliştirdiğinizi düşünün. Kullanıcılar görevlerini "Bekleyen" veya "Tamamlanmış" olarak filtreleyebilmelidir. Mitsuki Repositories ile bu işlemi gerçekleştirmek oldukça basittir. Frontend tarafından gönderilen bir filtre parametresini alarak, repository'nizin where metodunu kullanırsınız. Örneğin:
// Örnek API endpoint (Node.js Express)
// app.get('/tasks', async (req, res) => {
// const { status, page = 0, size = 10 } = req.query;
// let query = Task.query();
// if (status) {
// query = query.where('status', status);
// }
// const tasks = await query.page(parseInt(page), parseInt(size));
// res.json({
// tasks: tasks.results.map(task => task.toJSON()),
// total: tasks.total,
// page: parseInt(page),
// size: parseInt(size)
// });
// });
Bu yaklaşım, kullanıcıların arayüzde yaptığı seçimlere göre veritabanından dinamik olarak veri çekilmesini sağlar. Mitsuki'nin sağladığı temiz API, bu tür dinamik sorguları yazmayı oldukça kolaylaştırır ve kodunuzun okunaklılığını artırır. Böylece, kullanıcıya hızlı ve etkili bir filtreleme deneyimi sunulabilir.
Veri Güncelleme (Update) ve Silme (Delete) Operasyonları: Mitsuki ile Kayıt Yönetimi Nasıl Sağlanır?
CRUD operasyonlarının son iki ayağı olan güncelleme ve silme işlemleri, veri yaşam döngüsünün kritik parçalarıdır. Mitsuki Repositories, bu operasyonları da güvenli ve verimli bir şekilde gerçekleştirmenizi sağlayan güçlü metodlar sunar. Bu bölümde, mevcut görev kayıtlarını nasıl güncelleyeceğimizi ve ihtiyacımız kalmayan kayıtları nasıl sileceğimizi örneklerle açıklayacağız.
Mevcut Kayıtları Güncelleme: update Metodu ile Verileri Değiştirme
Bir görev kaydının başlığını, açıklamasını veya durumunu değiştirmek gibi senaryolar, güncelleme operasyonlarını gerektirir. Mitsuki, modeliniz üzerinde update metodunu kullanarak bu işlemi oldukça basitleştirir. Güncelleme yaparken, sadece değiştirmek istediğiniz alanları belirtmeniz yeterlidir. Diğer alanlar olduğu gibi kalır.
// Devam eden index.js dosyasında
async function updateTasks() {
console.log('\n--- Görevleri Güncelleme İşlemleri ---');
// Bir görevi bulup güncelleme
const taskToUpdate = await Task.query().findOne({ title: 'Mitsuki Rehberini Yaz' });
if (taskToUpdate) {
const updatedTask = await taskToUpdate.$query().patch({
status: 'completed',
description: 'Mitsuki rehber makalesi başarıyla tamamlandı.'
});
console.log('Görev başarıyla güncellendi:', updatedTask.toJSON());
} else {
console.log('Güncellenecek görev bulunamadı.');
}
// Birden fazla görevi toplu olarak güncelleme (örneğin, tüm bekleyen görevleri iptal etme)
// Dikkat: Gerçek senaryolarda bu tür toplu güncellemeleri dikkatli yapmalısınız.
// const bulkUpdateResult = await Task.query().where('status', 'pending').patch({ status: 'cancelled' });
// console.log(${bulkUpdateResult} adet görev iptal edildi.);
}
// main fonksiyonunu güncelle
async function main() {
// ... (yukarıdaki kurulum, insert ve read kodları) ...
await updateTasks();
// ... (deleteTasks fonksiyonunu çağıracağız) ...
}
main();
Yukarıdaki örnekte, önce belirli bir başlığa sahip görevi bulup, ardından bu görevin status ve description alanlarını güncelliyoruz. Mitsuki'nin patch metodu, sadece verilen alanları günceller ve diğer alanları etkilemez. Bu yaklaşım, kısmi güncellemeler için idealdir ve gereksiz veri transferini engeller.
Kayıtları Silme: delete ve Soft Delete Yaklaşımları
Bir görevin yaşam döngüsünün sonunda, o görevi sistemden kaldırmak gerekebilir. Mitsuki, kayıtları kalıcı olarak silmek için delete metodunu sunar. Ancak çoğu iş uygulamasında, verilerin kalıcı olarak silinmesi yerine "arşivlenmesi" veya "mantıksal olarak silinmesi" (soft delete) tercih edilir. Soft delete, verilerin hala veritabanında durduğu ancak uygulamanın normal akışında görünmediği anlamına gelir.
// Devam eden index.js dosyasında
async function deleteTasks() {
console.log('\n--- Görevleri Silme İşlemleri ---');
// Belirli bir görevi kalıcı olarak silme (Hard Delete)
const taskToDelete = await Task.query().findOne({ title: 'Alışveriş Yap' });
if (taskToDelete) {
await taskToDelete.$query().delete();
console.log('Görev başarıyla silindi (Hard Delete).');
} else {
console.log('Silinecek görev bulunamadı.');
}
// Soft Delete yaklaşımı
// Task modelimize 'deletedAt' adında yeni bir alan eklediğimizi varsayalım
// config.js veya Task.js modelimizde bunu tanımlamamız gerekir.
// Gerçek bir soft delete için Task modelinde 'deleted_at' sütunu olmalı
// ve Mitsuki modelinizin bu alanı otomatik yönetmesi için bir mekanizma eklenmeli.
// Basit bir örnek için, manuel olarak güncelleyelim:
const taskToSoftDelete = await Task.query().findOne({ title: 'Mitsuki Rehberini Yaz' }); // Bu görev tamamlandı olarak işaretlenmişti.
if (taskToSoftDelete) {
await taskToSoftDelete.$query().patch({ deletedAt: new Date().toISOString() });
console.log('Görev başarıyla silindi (Soft Delete).');
} else {
console.log('Soft delete yapılacak görev bulunamadı.');
}
// Soft delete edilmiş görevleri sorgulama (yalnızca aktif olanları getirme)
const activeTasks = await Task.query().whereNull('deletedAt');
console.log('Aktif görevler:', activeTasks.map(task => task.toJSON()));
}
// main fonksiyonunu güncelle
async function main() {
// ... (yukarıdaki kurulum, insert, read ve update kodları) ...
await deleteTasks();
console.log('\n--- Tüm CRUD Operasyonları Tamamlandı ---');
}
main();
Kalıcı silme işlemi için delete() metodunu kullanırız. Ancak soft delete için, modelimize deletedAt gibi bir zaman damgası alanı ekleyerek, bir kaydı silmek yerine bu alanı doldururuz. Sorgulama yaparken ise, deletedAt alanı null olan kayıtları filtreleyerek sadece aktif olanları getiririz. Bu yaklaşım, silinen verilere daha sonra ihtiyaç duyulduğunda geri dönüş imkanı sunar ve denetlenebilirlik açısından önemlidir.
Vaka Analizi 3: Kullanıcının Görevlerini Silme veya Arşivleme Seçenekleri Sunan Bir Arayüz
Bir web uygulamasında, kullanıcılar tamamlanmış görevleri "Sil" veya "Arşivle" butonuyla yönetmek isteyebilir. "Sil" butonu, aslında bir soft delete işlemi başlatarak görevin deletedAt alanını doldurur. "Arşivle" butonu ise, görevin durumunu "archived" gibi farklı bir statüye geçirir. Bu, kullanıcının verilerini yanlışlıkla silmesini önlerken, yöneticilerin denetim kayıtlarına erişmesine veya kullanıcıların kendi arşivlenmiş öğelerini görmesine olanak tanır. Mitsuki Repositories, bu tür iş mantığını veri erişim katmanından soyutlayarak, uygulamanızın daha güvenli ve esnek olmasını sağlar.
Özetle, Mitsuki Repositories, hem basit hem de karmaşık veri manipülasyonu ihtiyaçlarınız için kapsamlı ve güvenilir bir çözüm sunar. Bu temel CRUD operasyonlarını anlamak, Mitsuki ile güçlü ve sürdürülebilir uygulamalar geliştirmenin ilk adımıdır.
Mitsuki Repositories ile İleri Seviye Yaklaşımlar: Performans, Güvenlik ve Mimari Optimizasyonları
Mitsuki Repositories'in temel CRUD yeteneklerinin ötesine geçerek, uygulamanızın performansını artırmak, güvenliğini sağlamak ve mimarisini optimize etmek için kullanabileceğiniz ileri seviye yaklaşımlar mevcuttur. Bu bölümde, verimli sorgulama teknikleri, işlem yönetimi, hata işleme ve güvenlik ipuçları üzerinde duracağız.
İlişkisel Veriler ve Eager/Lazy Loading
Gerçek dünya uygulamalarında, veritabanı tabloları genellikle birbiriyle ilişkilidir (örneğin, bir görev birçok kullanıcıya atanabilir veya bir görev birçok etikete sahip olabilir). Mitsuki, bu ilişkileri yönetmek için güçlü mekanizmalar sunar. İlişkisel verileri sorgularken, performans açısından Eager Loading (Hevesli Yükleme) ve Lazy Loading (Tembel Yükleme) kavramları devreye girer.
- Lazy Loading: Varsayılan olarak, bir model sorgulandığında yalnızca o modele ait veriler getirilir. İlişkili veriler, onlara ihtiyaç duyulduğunda ayrı bir sorgu ile yüklenir. Bu, "N+1 sorgu problemi"ne yol açabilir; yani, N adet ana kayıt için N adet ek sorgu anlamına gelir.
- Eager Loading: İlişkili verilerin, ana sorgu ile birlikte tek seferde getirilmesidir. Bu, özellikle birden fazla ilişkili veriye ihtiyaç duyduğunuz durumlarda sorgu sayısını azaltarak performansı önemli ölçüde artırır. Mitsuki'de
withGraphFetchedveyawithGraphJoinedgibi metodlar bu amaçla kullanılır.
// models/User.js - Örnek bir kullanıcı modeli
const { Model } = require('mitsuki-repo');
class User extends Model {
static get tableName() { return 'users'; }
static get relationMappings() {
return {
tasks: {
relation: Model.HasManyRelation,
modelClass: require('./Task'),
join: {
from: 'users.id',
to: 'tasks.userId' // Bir kullanıcının birden çok görevi olabilir
}
}
};
}
}
module.exports = User;
// Bir kullanıcının tüm görevlerini eager loading ile getirme
const userWithTasks = await User.query().withGraphFetched('tasks').findById(1);
console.log('Kullanıcı ve görevleri:', userWithTasks.toJSON());
Bu örnek, bir kullanıcıyı ve ona ait tüm görevleri tek bir sorguda nasıl getirebileceğimizi gösterir. Bu, özellikle bir sayfa yüklemesinde birden fazla ilişkili veri kümesini görüntülemeniz gerektiğinde performansı dramatik bir şekilde artırır.
İşlem Yönetimi (Transactions) ve Hata Yakalama
Veritabanı işlemleri, birden fazla adımı içeren ve tüm adımların başarılı olması veya hiçbirinin olmaması gereken durumlar için önemlidir. Örneğin, bir görevi bir kullanıcıya atarken, görevin durumunu güncellemek ve kullanıcının bildirim listesine bir kayıt eklemek gibi. Bu tür durumlarda veritabanı işlemleri (transactions) kullanılır.
// Bir işlem içinde birden fazla operasyon
const { knex } = require('mitsuki-repo'); // knex instance'ı config.js'den geliyor
async function assignTaskTransaction(taskId, userId) {
const transaction = await Task.startTransaction(); // İşlemi başlat
try {
// Görevi güncelle
await Task.query(transaction).findById(taskId).patch({ userId: userId, status: 'assigned' });
// Kullanıcıya bildirim ekle (varsayımsal Notification modeli)
// await Notification.query(transaction).insert({ userId: userId, message: Yeni görev atandı: ${taskId} });
await transaction.commit(); // Tüm işlemler başarılıysa kaydet
console.log('Görev atama işlemi başarılı.');
} catch (error) {
await transaction.rollback(); // Herhangi bir hata durumunda tüm değişiklikleri geri al
console.error('Görev atama işlemi başarısız, geri alındı:', error.message);
}
}
// Kullanım örneği
// assignTaskTransaction(1, 2); // Görev ID 1'i Kullanıcı ID 2'ye ata
startTransaction(), commit() ve rollback() metodları, işlemlerinizi güvenli bir şekilde yönetmenizi sağlar. Herhangi bir adımda bir hata oluşursa, rollback() ile tüm işlemler geri alınır ve veritabanı tutarlı bir durumda kalır.
Güvenlik İpuçları ve Doğrulama Mekanizmaları
Veritabanı güvenliği, her uygulamanın olmazsa olmazıdır. Mitsuki Repositories, SQL enjeksiyonu gibi yaygın güvenlik açıklarına karşı yerleşik korumalar sunsa da, ek önlemler almak önemlidir:
- Girdi Doğrulama (Input Validation): Mitsuki'nin
jsonSchemaözelliği, modelinize gelen verilerin tipini ve formatını doğrulamak için harika bir başlangıç noktasıdır. Ancak, karmaşık iş kurallarınızı ve kullanıcı tarafından gönderilen tüm verileri ek güvenlik katmanlarıyla (örneğin, Joi veya Yup gibi doğrulama kütüphaneleriyle) sunucu tarafında doğrulamak hayati öneme sahiptir. - Yetkilendirme (Authorization): Kullanıcının belirli bir kaynağa (örneğin, bir görev kaydına) erişme veya onu değiştirme yetkisinin olup olmadığını kontrol etmek, repository katmanından önce veya repository metodları içinde yapılmalıdır. Mitsuki'nin kendisi yetkilendirme sağlamaz, ancak repository metodlarınıza yetkilendirme kontrollerini entegre edebilirsiniz.
- Parameterized Queries: Mitsuki, kullandığı ORM/query builder sayesinde sorguları otomatik olarak parametreleştirir. Bu, kullanıcı girdilerinin doğrudan SQL sorgularına gömülmesini engelleyerek SQL enjeksiyonu saldırılarına karşı koruma sağlar.
Mobil Uyumluluk ve Duyarlı Tasarım için İpuçları
Mitsuki Repositories, backend'de veri erişimini yönettiği için doğrudan mobil uyumlulukla ilgili değildir. Ancak, repository'den gelen verilerin mobil cihazlarda nasıl sunulduğu, kullanıcı deneyimi açısından kritik öneme sahiptir.
Repository'den gelen veriler genellikle JSON formatında bir API aracılığıyla frontend'e (web veya mobil uygulama) ulaştırılır. Frontend'in görevi, bu veriyi farklı ekran boyutlarına ve cihaz türlerine uygun şekilde görüntülemektir. Duyarlı tasarım (Responsive Design) ilkeleri burada devreye girer. HTML, CSS ve JavaScript kullanarak, uygulamanızın farklı cihazlarda aynı içeriği optimum şekilde sunmasını sağlayabilirsiniz.
ID
Başlık
Açıklama
Durum
Vaka Analizi 4: Görev Listesinin Mobil ve Masaüstü Arayüzlerinde Farklı Şekilde Gösterilmesi
Yukarıdaki HTML ve CSS örneğinde, bir görev listesi tablosu tanımlanmıştır. Masaüstü görünümünde klasik bir tablo olarak gösterilirken, ekran genişliği 600 pikselin altına düştüğünde (mobil cihazlar için tipik bir eşik), tablo hücreleri blok elemanlara dönüştürülür ve her bir hücrenin solunda ilgili başlık görünür. Bu sayede, geniş tablo verileri bile küçük ekranlarda okunabilirliğini korur. Mitsuki Repositories, bu verileri tutarlı ve güvenilir bir şekilde sağladığı sürece, frontend katmanı bu verileri alıp, farklı kullanıcı deneyimlerine göre esnek bir şekilde sunabilir.
Bu ileri seviye yaklaşımlar, Mitsuki Repositories ile çalışırken uygulamanızın daha sağlam, güvenli ve performanslı olmasını sağlar. Doğru stratejilerle, veri katmanınızı bir avantaj haline getirebilirsiniz.
Sonuç ve Sıkça Sorulan Sorular (SSS)
Bu rehber boyunca, Mitsuki Repositories'in ne olduğundan, temel CRUD operasyonlarını nasıl gerçekleştireceğimizden ve ileri seviye kullanım ipuçlarından bahsettik. Veri yönetiminin karmaşık dünyasında, Mitsuki gibi bir repository katmanı kullanmak, geliştirme sürecinizi büyük ölçüde basitleştirir, kodunuzu daha düzenli hale getirir ve uzun vadede projenizin sürdürülebilirliğini artırır. Gördüğümüz gibi, veri erişim katmanını soyutlamak, uygulamanızın veritabanı teknolojisinden bağımsız olmasını sağlar, test edilebilirliğini artırır ve ekip içinde tutarlı bir geliştirme pratiği oluşturur.
Mitsuki Repositories, sıfırdan başlayan bir geliştiricinin bile kolayca adapte olabileceği, ancak deneyimli kullanıcılar için de derinlemesine optimizasyon ve esneklik sunan bir yaklaşımdır. Veri oluşturma, okuma, güncelleme ve silme işlemlerini güvenle gerçekleştirirken, performans artırma, işlem yönetimi ve güvenlik konularında da önemli avantajlar elde edersiniz. Uygulamanızın veri katmanını modern standartlara uygun hale getirmek istiyorsanız, Mitsuki Repositories'i tercih etmek, projenize değer katacaktır.
Umarız bu kapsamlı rehber, Mitsuki Repositories'e olan yolculuğunuzda size yol gösterici olmuştur. Şimdi, konuya dair sıkça karşılaşılan bazı soruları yanıtlayalım:
Sıkça Sorulan Sorular (SSS)
| Soru | Cevap |
|---|---|
| Mitsuki hangi veritabanı sistemlerini destekler? | Mitsuki Repositories, mimari olarak soyut bir katman olduğu için, arkasındaki veritabanı adaptörüne bağlı olarak çeşitli veritabanlarını destekleyebilir. Bu rehberde SQLite kullandık, ancak PostgreSQL, MySQL, MSSQL gibi ilişkisel veritabanlarının yanı sıra, uygun adaptörlerle MongoDB veya Cassandra gibi NoSQL veritabanlarını da destekleyebilir. Temel prensip, Mitsuki'nin kullandığı ORM/query builder'ın desteklediği her veritabanı ile uyumlu çalışabilmesidir. |
| Mitsuki repository kullanmak projenin karmaşıklığını artırır mı? | Başlangıçta ek bir soyutlama katmanı getirdiği için küçük bir öğrenme eğrisi olabilir. Ancak uzun vadede, kodun düzenli, modüler ve test edilebilir olmasını sağlayarak karmaşıklığı azaltır. Doğrudan veritabanı sorgularının kodun her yerine dağılmasını engeller ve iş mantığını veritabanı detaylarından ayırarak daha temiz bir mimari sunar. Bu, özellikle büyük ve uzun ömürlü projelerde büyük bir avantajdır. |
| Performans optimizasyonu için ek olarak neler yapılabilir? | Mitsuki kullanırken performans optimizasyonu için şunlar yapılabilir:
|
| Mitsuki ile birleşik sorgular (joins) nasıl ele alınır? | Mitsuki'nin temelini oluşturan ORM/query builder, ilişkisel veritabanlarındaki birleşik sorguları (JOINs) destekler. withGraphJoined gibi metodlar, ilişkili tabloları JOIN kullanarak ana sorgunuza dahil etmenizi sağlar. Bu, birden fazla tablodan gelen verileri tek bir sonuç kümesinde birleştirmek için güçlü bir yoldur ve özellikle raporlama veya karmaşık veri görüntülerinde kullanılır. |
| Test yazarken Mitsuki'nin faydaları nelerdir? | Mitsuki Repositories, test edilebilirliği önemli ölçüde artırır. İş mantığınızı veritabanından soyutladığı için, gerçek bir veritabanı bağlantısı kurmadan repository'leri "mock" (sahte) edebilirsiniz. Bu, unit testlerin çok daha hızlı çalışmasını sağlar ve test ortamının karmaşıklığını azaltır. Bağımlılık enjeksiyonu prensibi sayesinde, bir kontrolcüye veya servise sahte bir repository örneği vererek, sadece o bileşenin kendi mantığını test edebilirsiniz. |