← Tüm yazılar

FluentValidation ile API iş akışına giriş kontrolü koymak

Geçersiz bir isteğin iş akışına hiç girmemesi, sonradan veritabanı hatası ayıklamaktan daha anlaşılır. FluentValidation ile bu kontrolü HTTP girişinde açıkça yapıyorum.

t.Turgay
FluentValidation ile API iş akışına giriş kontrolü koymak

Boş başlıkla gelen isteğin veritabanı katmanında hata vermesini beklemek gereksiz yere uzun bir yol. API girişinde alan sözleşmesini denetlersem kullanıcı hangi alanı düzelteceğini görür, iş servisi de biçim kontrolünü tekrar tekrar yazmaz. FluentValidation'ı bu sınırda kullanıyorum; yetki veya yayınlama kararını aynı validator içine doldurmuyorum.

Küçük bir isteğin kabul sözleşmesi

Arşivde oluşturma, güncelleme ve onay işlemlerinin ayrı olduğu API yapıları var. Aşağıdaki bağımsız Minimal API örneği bu akışların yalnız giriş kontrolünü gösteriyor. CreateDraft için başlık boş olamaz ve uzunluk 120'yi aşamaz. Geçerli istekte veri kaydedilmiyor; endpoint başlığı geri döndürüyor.

using FluentValidation;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
var builder=WebApplication.CreateBuilder(args);
builder.Services.AddScoped<IValidator<CreateDraft>,DraftValidator>();
var app=builder.Build();
app.MapPost("/drafts",async(CreateDraft input,IValidator<CreateDraft> validator,CancellationToken token)=>{
    var validation=await validator.ValidateAsync(input,token);
    if(!validation.IsValid)return Results.ValidationProblem(validation.ToDictionary());
    return Results.Ok(new {input.Title});
});
app.Run();
public record CreateDraft(string Title);
public class DraftValidator:AbstractValidator<CreateDraft>
{
    public DraftValidator()=>RuleFor(x=>x.Title).NotEmpty().MaximumLength(120);
}

Validator DI üzerinden Scoped olarak çözülüyor ve ValidateAsync çağrısına istek token'ı veriliyor. Başarısızlıkta Results.ValidationProblem alan adıyla ilişkilendirilebilir hata sözlüğü üretir. Başarılı yanıt, bu küçük endpoint'in doğrulamayı geçtiğini gösterir; veritabanı transaction'ı veya kalıcı taslak kaydı kanıtı değildir.

Alan kuralı ile iş kararı aynı yerde olmamalı

Başlığın zorunluluğu, metin uzunluğu ve sayısal aralıklar alan kurallarıdır. “Bu taslak artık yayımlanamaz”, “kullanıcı bu projeyi düzenleyemez” veya “aynı işlem daha önce tamamlandı” kararları ise mevcut iş durumuna bağlıdır. Bunları servis ve yetki sınırında değerlendiririm. Validator'ı her tabloya sorgu gönderen gizli bir iş servisine çevirmek akışı anlamayı zorlaştırır.

Veritabanı tekilliğini önceden sorgulamak kullanıcı deneyimini iyileştirebilir ama eşzamanlı iki isteği tek başına engellemez. Gerçek unique kısıtı ve onun kontrollü hata eşlemesi yine gerekir. Aynı şekilde biçimi geçerli bir kimlik, kullanıcının o kayda erişebileceğini söylemez.

Async kural varsa async yürütme gerekir

Örnekteki kurallar eşzamanlı olsa da ValidateAsync yolu seçilmiş. Sonradan MustAsync gibi bir kural eklendiğinde çağrı zinciri onu bekleyebilir. ASP.NET'in senkron otomatik doğrulama hattına async kuralları gelişigüzel yerleştirmem; kullanılan entegrasyonun desteklediği davranışı doğrularım. Bir action filter veya endpoint katmanı explicit async doğrulamayla bu sınırı görünür tutabilir.

CancellationToken yalnız parametrede durmamalı; validator içinde iptal edilebilir bir alt çağrı varsa ona da aktarılmalı. Alan doğrulamasının başlatılmış ama artık sonucu kullanılmayacak işleri biriktirmesini istemem.

Normalizasyon ile doğrulamayı karıştırmamak

Başlık kenar boşluklarının saklanmayacağı bir sözleşme varsa Trim işleminin ne zaman yapıldığı açık olmalı. Validator içinde nesneyi gizlice değiştirmek yerine normalizasyonu ayrı bir adımda ele alırım. Son kabul edilen metnin kurallara uyduğunu da doğrularım; doğrulamadan sonra başka bir dönüşümün sınırı aşmasına izin vermem.

Uzunluk sayımı da kullandığım string modeline bağlıdır. .NET String.Length görünür karakter sayısı ile her Unicode durumda aynı değildir. Çok dilli içerikte limitin kullanıcıya nasıl anlatıldığı ve veri kolonunun hangi uzunluğu kabul ettiği birlikte düşünülmeli; yalnız textarea üzerindeki maxlength yeterli sayılmaz.

400 yanıtı formda işe yaramalı

İstemci alan hatalarını kendi girdileriyle eşleyebilmeli. “İşlem başarısız” mesajı tek başına Title'ın boş olduğunu söylemez. Form ilk açılışta her alanı kırmızı yapmak yerine gönderim denemesinden sonra hatayı gösterir. Kaydet düğmesini eksik alan yüzünden sessizce kapatmak yerine kullanıcıya düzeltilecek yeri anlatmak daha yararlıdır; istek sürerken çift gönderim ayrıca engellenir.

Testte boş metin, boşluk, 120 ve 121 uzunluklu başlık, bozuk JSON ve geçerli istek bulunur. Geçersiz istek iş servisine ulaşmamalı. Bu örneğe gerçek yazma operasyonu eklenirse authentication, authorization, transaction ve kalıcı sonuç kontrolü de kendi katmanlarında tamamlanmalıdır.

FluentValidation ASP.NET entegrasyonu; Async doğrulama kuralları.

✳ Bu yörüngenin sonuna geldin.
Diğer yazıları keşfet →
turgay.Biraz kod, biraz piksel, bolca merak.© 2026 · Dünya’dan sevgilerle ✳