Node.js İle Veri Doğrulama İçin Joi Kütüphanesi Kullanımı Nasıl Yapılır?

Node.js İle Veri Doğrulama İçin Joi Kütüphanesi Kullanımı Nasıl Yapılır?
Node.js İle Veri Doğrulama İçin Joi Kütüphanesi Kullanımı Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Bu rehberdeki örnekleri uygulayabilmek için bilgisayarınızda Node.js'in güncel bir sürümünün (v18 veya üzeri önerilir) yüklü olması gerekmektedir. Projenizi başlatmak için bir terminal açın ve aşağıdaki adımları takip edin.

Öncelikle projeniz için bir dizin oluşturun ve gerekli kütüphaneyi yükleyin:

mkdir joi-egitim
cd joi-egitim
npm init -y
npm install joi

Bu komutlar, projenizi başlatacak ve Joi paketini node_modules klasörünüze ekleyecektir. Artık kodlamaya başlamak için hazırsınız.

Joi ile Temel Veri Doğrulama Adımları

Joi'nin temel çalışma prensibi, verinin uyması gereken bir "şema" (schema) tanımlamaktır. Şemalar, verinin tipini, zorunluluğunu ve özel kısıtlamalarını içerir. İlk olarak, basit bir kullanıcı kayıt verisini doğrulayan bir örnek yapalım.

const Joi = require('joi');

const schema = Joi.object({
    kullaniciAdi: Joi.string().alphanum().min(3).max(30).required(),
    yas: Joi.number().integer().min(18).max(99)
});

const veri = { kullaniciAdi: 'ahmet', yas: 25 };
const { error, value } = schema.validate(veri);

if (error) {
    console.log('Doğrulama hatası:', error.details[0].message);
} else {
    console.log('Doğrulanmış veri:', value);
}

Bu örnekte, kullaniciAdi alanının sadece alfanümerik karakterlerden oluşması ve en az 3 karakter olması gerektiğini belirttik. validate fonksiyonu, veriyi kontrol eder ve bir hata nesnesi veya doğrulanmış veriyi döndürür.

Karmaşık Nesne Yapıları ve İç İçe Doğrulama

Gerçek dünya uygulamalarında veriler genellikle iç içe geçmiş nesnelerden oluşur. Joi, Joi.object() yapısını iç içe kullanarak bu tür karmaşık yapıları kolayca yönetmenizi sağlar. Aşağıda, bir adres bilgisi içeren kullanıcı profilini doğrulayan bir örnek bulunmaktadır.

const profilSema = Joi.object({
    isim: Joi.string().required(),
    adres: Joi.object({
        sehir: Joi.string().required(),
        postaKodu: Joi.string().pattern(/^[0-9]{5}$/)
    })
});

const profilVerisi = {
    isim: 'Can',
    adres: { sehir: 'İstanbul', postaKodu: '34000' }
};

const sonuc = profilSema.validate(profilVerisi);
console.log(sonuc.error ? 'Hata var' : 'Veri geçerli');

Burada pattern metodu ile posta kodu için bir Regex (Düzenli İfade) kullandık. Bu sayede sadece 5 haneli sayısal değerlerin kabul edilmesini sağladık.

Joi ile Güvenlik ve Veri Sanitizasyonu

Joi sadece doğrulama yapmaz, aynı zamanda veriyi temizleyebilir (sanitization). Örneğin, kullanıcıdan gelen boşlukları temizlemek veya veriyi belirli bir formata sokmak için stripUnknown veya trim metodlarını kullanabiliriz.

Kritik Güvenlik Uyarısı: Veri doğrulaması, XSS veya SQL Injection gibi saldırılara karşı ilk savunma hattıdır. Ancak, veritabanına veri gönderirken her zaman parametreli sorgular (prepared statements) kullanmalı ve kullanıcı girdilerini asla doğrudan sorgu içine gömmemelisiniz.

const girisSema = Joi.object({
    email: Joi.string().email().lowercase().trim().required(),
    sifre: Joi.string().min(8).required()
});

const hamVeri = { email: '  ORNEK@mail.com  ', sifre: '12345678' };
const { value } = girisSema.validate(hamVeri);

console.log('Temizlenmiş veri:', value);

lowercase() ve trim() metodları, veriyi veritabanına kaydetmeden önce standart bir formata getirerek tutarlılığı artırır.

Doğrulama Yöntemlerinin Karşılaştırılması

Veri doğrulama süreçlerinde kullanılan farklı yaklaşımları aşağıdaki tabloda inceleyebilirsiniz:

Yöntem Avantajı Dezavantajı
Manuel Kontrol (if/else) Bağımlılık yok Kod tekrarı, hata payı yüksek
Joi Kütüphanesi Okunabilir, geniş özellik seti Ekstra kütüphane boyutu
Express-Validator Middleware odaklı Daha kısıtlı şema yapısı

Hata Yönetimi ve Özelleştirilmiş Mesajlar

Joi'nin varsayılan hata mesajları İngilizcedir. Kullanıcılarınıza daha anlaşılır mesajlar göstermek için messages özelliğini kullanabilirsiniz. Bu, özellikle kullanıcı deneyimi (UX) açısından çok önemlidir.

const ozelSema = Joi.object({
    yas: Joi.number().min(18).messages({
        'number.min': 'Üzgünüz, 18 yaşından küçükler kayıt olamaz.',
        'number.base': 'Yaş alanı bir sayı olmalıdır.'
    })
});

const sonuc = ozelSema.validate({ yas: 15 });
if (sonuc.error) {
    console.log(sonuc.error.details[0].message);
}

Sıkça Sorulan Sorular

Joi, Express.js ile nasıl kullanılır?

Joi'yi Express.js içinde bir middleware olarak kullanarak, rota (route) seviyesinde verileri otomatik doğrulayabilirsiniz.

Joi ile veritabanı kontrolü yapılabilir mi?

Joi temel olarak veri formatını doğrular. Veritabanında bir kullanıcı olup olmadığını kontrol etmek için Joi'nin external veya custom doğrulama metodlarını kullanabilirsiniz.

Performans üzerinde etkisi nedir?

Joi oldukça hızlıdır, ancak çok karmaşık şemalarda her istekte doğrulama yapmak küçük bir gecikmeye neden olabilir. Yine de güvenlik için bu maliyet kabul edilebilir düzeydedir.

Joi ile dosya yükleme doğrulanabilir mi?

Evet, dosya boyutu ve MIME tipi gibi özellikleri doğrulamak için Joi kullanılabilir.

Joi güncellemelerini nasıl takip ederim?

Joi'nin resmi GitHub deposunu veya npm sayfasını takip ederek en güncel sürüm ve değişiklik notlarını görebilirsiniz.

İleri Seviye Joi İpuçları ve Şema Modülerliği

Büyük ölçekli Node.js projelerinde, tüm doğrulama şemalarını tek bir dosyada tutmak zamanla yönetilemez bir hale gelir. Joi şemalarınızı modüler hale getirerek, farklı servisler ve kontrolcüler arasında yeniden kullanılabilir doğrulama mantıkları oluşturabilirsiniz.

Örneğin, kullanıcı kaydı ve profil güncelleme işlemleri için ortak bir "şifre" kuralı tanımlayarak kod tekrarını önleyebilirsiniz:

const Joi = require('joi');

// Ortak kuralları bir nesnede toplayın
const commonSchemas = {
  password: Joi.string().min(8).pattern(new RegExp('^[a-zA-Z0-9]{3,30}$')).required()
};

// Şemaları modüler şekilde oluşturun
const registerSchema = Joi.object({
  email: Joi.string().email().required(),
  password: commonSchemas.password
});

const updatePasswordSchema = Joi.object({
  oldPassword: commonSchemas.password,
  newPassword: commonSchemas.password
});

Bu yaklaşım, uygulamanızın farklı noktalarında aynı doğrulama mantığını korumanıza yardımcı olurken, merkezi bir noktadan güncelleme yapmanıza olanak tanır.

Joi Şemaları İçin Birim Testi (Unit Testing) Yazma

Doğrulama şemalarınızın beklediğiniz gibi çalıştığından emin olmak için Jest veya Mocha gibi test kütüphaneleri ile birim testleri yazmak kritik bir başarı faktörüdür. Bir şemanın geçersiz girdilerde hata fırlattığından ve geçerli girdilerde hata döndürmediğinden emin olmalısınız.

Aşağıdaki örnek, Jest kullanarak bir şemanın doğruluğunu nasıl test edebileceğinizi göstermektedir:

const { registerSchema } = require('./schemas');

describe('Kullanıcı Kayıt Şeması Testleri', () => {
  test('Geçerli veri ile doğrulama başarılı olmalı', () => {
    const data = { email: 'test@example.com', password: 'password123' };
    const { error } = registerSchema.validate(data);
    expect(error).toBeUndefined();
  });

  test('Geçersiz email formatında hata dönmeli', () => {
    const data = { email: 'invalid-email', password: 'password123' };
    const { error } = registerSchema.validate(data);
    expect(error).toBeDefined();
    expect(error.details[0].path[0]).toBe('email');
  });
});

Bu testler, gelecekte şemalarınızda yapacağınız değişikliklerin mevcut API uç noktalarınızı bozup bozmadığını anlamanızı sağlayan bir güvenlik ağı görevi görür.

Doğrulama Performansını Optimize Etme

Joi, doğrulama sırasında oldukça hızlıdır ancak çok karmaşık ve iç içe geçmiş şemalarda binlerce istek altında performans darboğazları yaşanabilir. Performansı artırmak için şu stratejileri izleyebilirsiniz:

  • Şemaları Önbelleğe Alın: Joi nesnelerini her istekte yeniden oluşturmak yerine, modül seviyesinde tanımlayarak bir kez derlenmesini sağlayın.
  • Gereksiz Doğrulamalardan Kaçının: Sadece API'ye gelen kritik verileri doğrulayın; veritabanından gelen ve zaten güvendiğiniz veriler için Joi kullanmaktan kaçının.
  • abortEarly Ayarı: Varsayılan olarak Joi, ilk hatayı bulduğunda durur. Eğer tüm hataları tek seferde görmek istiyorsanız abortEarly: false seçeneğini kullanın, ancak bunun küçük bir performans maliyeti olduğunu unutmayın.
const schema = Joi.object({ ... });

// Performans için sadece gerekli durumlarda tüm hataları toplayın
const { error } = schema.validate(data, { abortEarly: false });

Sonuç

Node.js ile veri doğrulama süreçlerinde Joi, sunduğu esneklik ve güvenlik standartları ile vazgeçilmez bir araçtır. Bu rehberde, temel şema oluşturmadan karmaşık nesne yapılarına, hata mesajlarının özelleştirilmesinden güvenlik odaklı veri temizlemeye kadar birçok kritik konuyu ele aldık. Uygulamalarınızda bu yöntemleri kullanarak daha kararlı ve güvenli sistemler inşa edebilirsiniz.

Yasal Uyarı ve Sorumluluk Reddi: Bu makaledeki kod örnekleri eğitim amaçlıdır. Uygulamanızın güvenliği için her zaman en güncel güvenlik yamalarını takip edin ve kullanıcı girdilerini veritabanına kaydetmeden önce mutlaka sunucu tarafında tekrar doğrulayın.

Bir sonraki adım olarak, Joi şemalarınızı Express.js middleware yapısıyla birleştirerek tüm API uç noktalarınızda otomatik bir doğrulama katmanı oluşturmayı deneyebilirsiniz.

Bu yazıya tepkinizi paylaşın:
Selin Yılmaz

Sürdürülebilir yaşam ve pratik ev yönetimi üzerine içerik stratejileri geliştiriyorum. Yalın anlatımı ve uygulanabilirliği ön planda tutan bir yazı dilim var.

Yorumlar (0)

Yorum Yaz