.Net Core Web API’de Fluent Validation Kullanımı

ismail kaşan
4 min readDec 10, 2021

--

Header İmage

Merhaba arkadaşlar. Yazılım projeleri büyüdükçe iş kuralları birbirine girmeye başlar. Karmaşıklık arttıkça işler içinden çıkılmaz bir hal alır. Özellikle iş katmanlarındaki validation için kullanılan if-else blokları olayları farklı boyutlara taşır. İş katmanındaki verileri doğrulamak için belli başlı kurallara sahip algoritmalar veya kütüphaneler tercih edilmektedir. Bu yazımızda .NET Core uygulamalarında Fluent Validation kütüphanesi ile nasıl veri doğrulaması yapılacağını inceleyeceğiz. Fluent Validation nedir? Bu kütüphanenin bize faydası ne? Neden kullanmalıyız? Önce bu sorulara cevap vereceğiz.

Fluent Validation Nedir?

Fluent Validation, iş nesneleri için KESİN olarak belirlenmiş doğrulama kuralları(örnek,password min 8 karakter olmalıdır.) oluşturmak için kullanılan bir .NET kütüphanesidir. Bu kütüphane adından da anlaşılacağı gibi Fluent Design Pattern kullanmaktadır.

Bu Fluent Design Pattern nedir? Kısaca bahsedelim. Nesnenin içindeki metodların geri dönüş tipleri yine o nesnenin kendisidir. Yani çağrılan her fonksiyon işini yaptıktan sonra, içinde olduğu nesneyi döner. Bu da her metodtan sonra lambda ifadeleri ile bir sonraki metodu çağırabiliriz. Bütün metodlar bir zincir gibi birbirine bağlanmış olur. Bundan dolayı tasarımsal olarak bütünlük çıkar ortaya. .Net’in kütüphanelerinde mevcut ve çokça kullanmışızdır. Örnek aşağıdaki gibidir. Metodlar bir birinin ardından çağrılmışlardır. Detay için burdan bakabilirisniz.

services.Scan(scan => scan
.FromApplicationDependencies()
.AddClasses(classes => classes.AssignableTo<IScopedLifetime>())
.AsImplementedInterfaces()
.WithScopedLifetime()
.AddClasses(classes => classes.AssignableTo<ITransientLifetime>())
.AsImplementedInterfaces()
.WithTransientLifetime()
.AddClasses(classes => classes.AssignableTo<ISingletonLifetime>())
.AsImplementedInterfaces()
.WithSingletonLifetime());

Fluent Validation kütüphanesi de bu tasarımı kullanır. Methodlar bir zincir gibi birbirine bağlı olduğu için akıcı bir şekilde kurallar silsilesi tanımlamamızı sağlar. Bir başka konu ise doğrulama katmanını iş katmanından ayırdığımız için daha yönetilebilir bir yapı elde etmiş oluyoruz.

Fluent Validation Avantajları Nelerdir?

1. Geliştirme süreçlerini hızlanmasını sağlar.

2. Doğrulama kurallarını yaptığımız katman ile iş katmanlarını ayırmamıza olanak tanır. Kuralları güzel ve okunabilir olacak şekilde yapılandırmamıza yardımcı olur.

3. Hız ve performansı artırır. Kuralları taşıyan nesneler değişmez nesnelerdir, yani onları bir kez oluşturup önbelleğe alabiliriz. Kurallar modelin bir parçası olduğunda, yani iş katmanına yazıldığında, her seferinde onları gereksiz yere çağırıp oluşturmak zorunda kalırız. Bu, küçük projede çalışırken bir sorun değildir, ancak entity sayısı fazla olan bir projede çalışırken performans sorunu ortaya çıkacaktır. Validation nesneleri cache’lendiğinde işlemler daha da hızlanacaktır.

.Net Core 3.1 Web API’de Fluent Validation Kullanımı

Github üzerindeki örnek proje üzerinden devam edeceğim. Proje buradan indirebilirsiniz.

İlk etapta projemde Product diye bir nesne var. Ve işlemleri bu nesne üzerinden örneklendirmeye çalışacağım. Product nesnesi kabaca aşağıdaki gibidir. Çünkü projedeki yapıda Id ve IsDeleted alanları BaseEntitiy’den türüyor.

public class Product
{
public long Id { get; set; }
public bool IsDeleted { get; set; }
public string Name { get; set; }
}

Kütüphaneyi kullanabilmek için Nuget üzerinden gerekli dll’leri indirmemiz gerekiyor. Bunun için aşağıdaki komutu projede package manager console’da yapıştırıp çalışmak yeterli olacaktır.

Install-Package FluentValidation.AspNetCore -Version 10.2.3
Package manager console. Domain katmanına kurdum. Bütün projelerim domainden referans aldığı için artık heryerden erişilebilir oldu.

Şimdi validation nesnesini hazırlamaya geldi. Projenin domain katmanında ProductValidator adında bir sınıf ekliyorum. Buradaki önemli nokta eklediğim validation sınıfının AbstractValidator<>’den türetilmesidir. AbstractValidator<Product> sınıfına kontrol edilecek nesneyi generic olarak verilmelidir. Örnek aşağıdaki gibi.

Nesnenin kurucu metodunda RuleFor(c => c.Name) metodu ile nesnenin kontrol edilecek alanlarına eriştikten sonra diğer metodlarla kuralları belirtiyoruz. Fluent Design Pattern kullanıldığı için lambda ifadeleri ile kurallar bir birine zincir gibi bağlanıyor.

Sırada hazıladığımız validation nesnesini projeye dahil etmeye geldi. Starup.cs dosyasında projenin container’ına dahil ediyoruz. Startup.cs de aşağıdaki satırları ekliyoruz.

Şimdi iş katmamızı işlettiğimiz yerde bu kontrolu yapacağız. ProductService.cs de constructor injection ile nesneyi ekliyoruz. Burada dikkat edeceğimiz nokta kütüphaneden gelen IValidator<Product> interface’den generic olarak alınan instance ile işlemleri kontrol ediyoruz. AddProduct(ProductInputDto productInputDto) methodunda gelen productInputDto’nun Mapper ile Product nesnesine çevrildikten sonra kontrolu Product nesnesi üzerinde yapıyoruz. Validation’ı geçerse nesne repoya gidecek ve veri tabanına yazılacak. Validation’ı geçmezse validation mesajları response edilecek.

Proje çalıştırıp resimdeki gibi bir tane istek gönderiyoruz.

Resimdeki gibi değerleri gönderiyoruz.

Sunucudan dönen cevaba bakalım.

3 tane mesaj döndü bize. bu mesajları biz ProductValidator nesnesinde kuralları tanımarken yazmıştık. Şimdi nesneyi değiştirip tekrar istek atalım.

Sunucudan dönen cevap başarılı oldu. Çünkü koyduğumuz kurallara takılmadı.

Fluent Validation kütüphanesinin metodlarıyla kendi uygulamanıza yönelik kuralları işletebilirsiniz. İş katmanına gelmeden önce verinin izole bir katmanda kontrol edilmesi çok avantajlıdır. Validation’ı geçemeyen verinin neden geçmediğini anlamlı mesajlarla kullanıcıya gösterilmiş oluyor. Umarım faydalı bir içerik omuştur.

Kaynaklar:

--

--

ismail kaşan
ismail kaşan

Written by ismail kaşan

I am a full stack developer since 2016.

Responses (1)