Şimdi bu işlere girişmeden önce, bir ara benim de uğraştığım ama sonra neyse ki başka alanlara yöneldiğim bir zaman vardı. O zamanlar frontend’de Vue.js ile uğraşıyordum, backend’de ise C# ve PostgreSQL fırtınaları esiyordu. Arada bir de Dapper’ı kullanıp duruyordum. Hani böyle hem öğrenmeye çalışırsın hem de bir yandan da ‘Bu işler nasıl oluyor?’ diye kafa patlatırsın ya, işte tam öyle bir dönemdi. Neyse efendim, bu deneyimlerden aklımda kalanları, özellikle de Vue.js’ten C# REST API’mize nasıl veri gönderdiğimizi anlatayım dedim. Hem belki birilerine faydası olur, hem de ben de şöyle bir hafızamı tazelemiş olurum.
Öncelikle neden böyle bir şeye ihtiyaç duyuyoruz, onu bir konuşalım. Genelde web uygulamalarında kullanıcı etkileşimleri sonucunda oluşan veriyi sunucuya iletmek gerekir. Bu veriler bir form doldurma olabilir, bir ayar kaydetme olabilir, ya da benim o dönemde çokça yaptığım gibi oyun içi bir aksiyonun kaydedilmesi falan filan. İşte tam bu noktada, frontend’de kullandığımız Vue.js’ten, backend’de çalışan C# REST API’mize güvenilir bir şekilde veri göndermemiz gerekiyor. Tabii bunu yapmanın türlü türlü yolları var ama en yaygın ve en sağlamlarından biri HTTP POST isteği göndermek. Bu arada, bu tür işlemleri yaparken veri yapısının doğru olması da çok önemli, yoksa backend’de çuvallıyoruz hemen. Hani böyle karşıdan gelen veriyi beklersin ama o beklediğin formatta gelmeyince program patlar ya, işte öyle bir durum. Bu yüzden DTO (Data Transfer Object) dediğimiz yapılar devreye giriyor. Basitçe, frontend’den gönderdiğimiz verinin backend’deki karşılığı gibi düşünebilirsiniz bunları.
Şimdi gelelim işin kod kısmına. Frontend’de Vue.js kullanırken, genellikle axios gibi kütüphanelerle HTTP istekleri yaparız. Çok da güzel çalışıyorlar, sağ olsunlar. Bir tane basit butonumuz var diyelim, bu butona basınca bir fonksiyon çalışacak ve o fonksiyon da bizim Vue component’imizdeki verileri alıp C# API’mize POST edecek. Bu Vue tarafı için şöyle bir şey hayal edebilirsiniz;
<template> <div> <input type="text" v-model="kullaniciAdi" placeholder="Kullanıcı Adı" /> <button @click="veriGonder">Gönder</button> </div> </template> <script> import axios from 'axios';export default { data() { return { kullaniciAdi: '' }; }, methods: { async veriGonder() { try { const response = await axios.post('/api/kullanici', { kullaniciAdi: this.kullaniciAdi }); console.log('Başarılı:', response.data); } catch (error) { console.error('Hata oluştu:', error); } } } }; </script>
Gördüğünüz gibi, gayet basit bir yapı. `kullaniciAdi` diye bir veri tutuyoruz, butona basılınca `veriGonder` fonksiyonu çalışıyor ve bu fonksiyon da axios ile `/api/kullanici` adresine POST isteği yapıyor. Gönderdiğimiz veri de `{ kullaniciAdi: this.kullaniciAdi }` şeklinde, yani bir JSON nesnesi. Bu JSON nesnesi de bizim backend’deki DTO’muza karşılık gelecek aslında. Bu arada, axios’un `async/await` ile kullanımı gerçekten hayat kurtarıyor, eskiden callbacklerle uğraşmak ne zordu hatırlamıyorum ama bayağı karışıktı galiba.
Şimdi bu POST isteği backend’de nasıl karşılanıyor ona bakalım. C# tarafında, ASP.NET Core ile bir REST API projesi kurduğumuzu varsayalım. Dapper’ı da veritabanı işlemleri için kullanacağız. Öncelikle, frontend’den gelen `kullaniciAdi` bilgisini karşılayacak bir DTO sınıfı oluşturmamız gerekiyor. Bu sınıfın adı ne olsa ki… Mesela `KullaniciIstekDto` diyebiliriz. Bu DTO, Vue’den gönderdiğimiz JSON yapısıyla birebir aynı olmalı. Yani, property ismi `kullaniciAdi` ise, DTO’daki property ismi de `KullaniciAdi` (veya C# convention’ına uygun bir şekilde) olmalı. Ardından, bu DTO’yu alacak bir controller action metodu yazacağız. Bu metodun `[HttpPost]` attribute’u ile işaretlenmesi önemli, ki gelen isteğin POST olduğunu anlasın API. Hatta parametre olarak da bu DTO’yu alacak şekilde tanımlayacağız. İşte tam olarak şöyle bir şey:
Şimdi buradaki kritik nokta şu: Eğer Vue’den gönderdiğimiz JSON yapısı ile DTO’muz eşleşmiyorsa, ASP.NET Core model binding yaparken hata verecektir. Bu yüzden property isimlerinin tutarlı olması hayati önem taşıyor. Diyelim ki Vue’den `kullaniciAdi` gönderdik ama C# DTO’muzda `UserName` diye bir property var. İşte orada işler karışıyor. Bu yüzden isimleri aynı tutmak en temizi. Eğer isimler farklı olacaksa, DTO üzerinde `[JsonProperty(“kullaniciAdi”)]` gibi attribute’lar kullanarak eşleştirmeyi sağlamanız gerekiyor. Ama bana sorarsanız, baştan isimleri aynı tutmak en kolayı. Neticede, bu işlerin amacı karmaşıklığı azaltmak değil mi?
Controller tarafında DTO’yu aldıktan sonra, artık veritabanı işlemlerine geçebiliriz. Burada Dapper devreye giriyor. Dapper, .NET için hızlı ve basit bir ORM (Object-Relational Mapper) diyebiliriz. Yani, SQL sorgularınızı yazmanızı ve sonuçları C# nesnelerine (bizim durumumuzda DTO’larımıza veya başka domain modellerimize) maplemenizi sağlıyor. Şöyle bir SQL sorgusu yazabiliriz;
INSERT INTO Kullanicilar (Adi) VALUES (@Adi)
Bu sorguyu Dapper ile çalıştırmak için bir `SqlConnection` nesnesi oluşturup, bu sorguyu ve DTO’muzdaki veriyi parametre olarak göndereceğiz. Dapper’ın `ExecuteAsync` metodu bu iş için ideal. İşte C# tarafında bu işlemin nasıl görünebileceğine dair basit bir örnek;
public class KullaniciIstekDto { public string KullaniciAdi { get; set; } }[ApiController] [Route("api/[controller]")] public class KullaniciController : ControllerBase { private readonly IDbConnection _dbConnection;
public KullaniciController(IDbConnection dbConnection) // Dependency Injection ile veritabanı bağlantısı alınır { _dbConnection = dbConnection; }
[HttpPost] public async Task<IActionResult> PostKullanici([FromBody] KullaniciIstekDto istek) { if (!ModelState.IsValid) { return BadRequest(ModelState); // Model doğrulaması başarısız olursa hata döndürülür }
var sql = "INSERT INTO Kullanicilar (Adi) VALUES (@Adi)"; await _dbConnection.ExecuteAsync(sql, new { Adi = istek.KullaniciAdi });
return Ok("Kullanıcı başarıyla eklendi."); // Başarılı olursa mesaj döndürülür } }
Bu örnekte, `KullaniciController` adında bir controllerimiz var. `PostKullanici` metodu `[HttpPost]` ile işaretlenmiş ve `KullaniciIstekDto` tipinde bir parametre alıyor. Veritabanı bağlantısı için `IDbConnection` dependency injection ile alınıyor. Ardından, basit bir SQL sorgusu ile `Kullanicilar` tablosuna veri ekleniyor. Dapper’ın `ExecuteAsync` metodu bu sorguyu güvenli bir şekilde çalıştırıyor. Parametre olarak `@Adi` yerine `new { Adi = istek.KullaniciAdi }` şeklinde bir anonim nesne göndererek SQL injection gibi güvenlik açıklarının önüne geçilmiş oluyor. Ne güzel değil mi? Hem hızlı hem de güvenli.
Şimdi gelelim “Yanlış yaptık → Doğru yaptık” kısmına. Diyelim ki biz baştan DTO’yu yanlış tanımladık. Mesela Vue’den `kullaniciAdi` gönderiyoruz ama backend’de DTO şöyle:
Bu durumda, `ModelState.IsValid` kontrolü `false` dönecek ve API, `BadRequest(ModelState)` ile bir hata mesajı döndürecektir. Kullanıcı tarafında da konsolda `Hata oluştu:` şeklinde bir log göreceğiz. Hani böyle ilk başta her şey yolunda sanırsın ama sonra bir bakmışsın ki olmamış 🙂
Peki ya doğru DTO ile yapsaydık? İşte o zaman yukarıda bahsettiğim gibi, `KullaniciIstekDto`’yu doğru tanımlayıp, Vue’den gelen veriyle eşleşmesini sağladığımızda, `ModelState.IsValid` kontrolü `true` dönecek ve veritabanı işlemi başarıyla gerçekleşecekti. Sonuç olarak da `Ok(“Kullanıcı başarıyla eklendi.”)` mesajını alacaktık. İşte bu kadar basit. Yani doğru DTO’yu kullanmak, işleri ne kadar kolaylaştırıyor, değil mi?
Bu arada, bu tür işlemler için genellikle `HttpClient` sınıfını da kullanabilirsiniz. Özellikle .NET Core’da `IHttpClientFactory` ile yönetilen bir `HttpClient` kullanımı, performans açısından daha iyi olabilir. Ama Dapper’la doğrudan sorgu çekmek de gayet hızlı bir yöntem. Hangisini kullanacağınız projenizin genel mimarisine ve sizin tercihlerinize bağlı.
Sonuç olarak, Vue.js’ten C# REST API’ye veri göndermek, doğru DTO kullanımı, axios gibi kütüphanelerle frontend isteği ve Dapper ile backend veritabanı işlemleri sayesinde oldukça basit ve etkili bir şekilde halledilebiliyor. Bu tür entegrasyonlar, modern web uygulamalarının temelini oluşturuyor ve bu bilgiyi edinmek gerçekten işinize yarayacaktır. Hani böyle bir proje yaparken “Aa evet, bunu böyle yapıyorduk!” dersiniz işte.
Eğer bu konularda daha fazla detaya inmek isterseniz, Google’da biraz arama yapabilirsiniz. Karşınıza çıkan kaynaklar da size yardımcı olacaktır. Tabii ki her zaman olduğu gibi, kendi deneyimleriniz ve testleriniz en doğru sonucu verecektir. Bazen bir şeyi bilmek yetmez, onu uygulamak da gerekir. O yüzden denemekten çekinmeyin.
Bu arada, eğer bu yazıyı okuyup “Ben de böyle bir şey yapmıştım ama farklıydı” diyenler varsa, yorumlarda paylaşabilirler. Bilgi paylaştıkça çoğalır sonuçta. Belki benim unuttuğum veya bilmediğim bir detay vardır kim bilir? 🙂 Hani bazen bir kod parçasını okursun ve “Aa evet, bunu böyle daha iyi yapabilirmişim!” dersin ya, işte öyle bir şey. Bu arada, bu tür konularla ilgili YouTube’da da çok güzel anlatımlar var, isterseniz buradan da bir göz atabilirsiniz.
Son olarak, bu konularda kendinizi geliştirmek istiyorsanız, Dapper’ın kendi dokümantasyonuna veya ASP.NET Core REST API geliştirme rehberlerine bakabilirsiniz. Eminim çok faydalı olacaktır. Unutmayın, kod yazmak, sadece komutları bir araya getirmek değil, aynı zamanda problem çözme sanatıdır. Ve bu sanatı icra ederken kullanacağınız araçlar ne kadar iyiyse, sonuç da o kadar muhteşem olur. İşte, bu kadar!