İçeriğe geç

C# .NET ile Dapper ve PostgreSQL: REST API Geliştirmede Pratik Deneyimlerim

Bazen oturup kod yazarken aklıma geliyor, Bursa’nın o serin akşamlarında, evde bilgisayar başında, dışarıda Uludağ’ın rüzgarı esiyor. Eşim ve çocuğumla geçirdiğim vakitler arasında, kodlama için pek zaman kalmıyor ama fikir üretmek için fırsat kolluyorum. Hatırlıyorum, geçen Pazar sabahı kahvaltıdan sonra, çocuk uyurken hızlıca bir REST API’ye baktım, PostgreSQL bağlantısını Dapper ile test ettim. Aslında o an dağcılık planları yapıyorduk ama kod aklımdan çıkmadı. Neyse efendim, bugün size C# ile Dapper kullanarak PostgreSQL’e nasıl bağlandığımı anlatayım, benim gibi geliştiriciler için pratik bir şeyler çıksın ortaya.

Evet, Dapper’ı ilk keşfettiğimde, Entity Framework’ten bıkmıştım biraz, ağır geliyordu projelerime. PostgreSQL’i severim, açık kaynak, güçlü, Bursa’daki bir projemde yerel veritabanı olarak kullandım. Dapper ise mikro ORM, hızlı sorgular için ideal. Bana göre, REST API geliştirirken, Dapper ile connection string’leri yönetmek çok pratik oluyor. Tabi, MySQL de kullanırım ama PostgreSQL’in JSON desteği falan, daha esnek geliyor.

Neden Dapper’ı Tercih Ediyorum?

Dapper, Stack Overflow’da Sam Saffron tarafından geliştirilmiş bir şey, sanırım. Hızlı map’leme yapıyor, SQL injection’a karşı güvenli. Benim deneyimime göre, büyük verilerde EF’den daha az bellek kullanıyor. Mesela bir tabloda 10 bin kayıt çekerken, Dapper saniyede bitiriyor, EF ise biraz oyalanıyor. Bu arada, geçen ay bir projede, Dapper’ı entegre ederken ufak bir hata yaptım, connection string’de parolayı yanlış yazmışım, saatlerce debug yaptım. Neyse ki NuGet’ten yükleyip, basit bir Install-Package Dapper komutuyla halletim.

Fakat, Dapper’ı kullanırken dikkat etmen gereken bir şey var, parametreli sorgular yazmak. Yoksa güvenlik sorunu çıkar. İşte bir örnek, basit bir SELECT için. Öncelikle using System.Data; ve using Dapper; ekliyorsun projene. Sonra connection açıyorsun.

using (var connection = new NpgsqlConnection(connectionString))
{
    var users = connection.Query<User>("SELECT * FROM users WHERE id = @Id", new { Id = 1 });
    return users;
}

Evet gayet güzel çalışıyor değil mi? Bu kodla, PostgreSQL’e bağlanıp veri çekiyorsun. Ben REST API’mde bu yapıyı kullanıyorum, .NET Core’da. Npgsql paketini de unutma, PostgreSQL için driver o. NuGet’ten Install-Package Npgsql.Dapper yapıyorsun, hazır.

Bu arada aklıma geldi, geçen hafta markette, çocuk arabasında uyurken, telefonuma bir kod fikri not aldım. Yanımda bir adam vardı, elektronik devrelerden bahsediyordu, gömülü sistemler işte. Ben de PHP’den Vue’ya geçişimi anlattım ona, sohbet uzadı. Ne alaka değil mi? 🙂 Kodlama her yerde aklıma geliyor, aile turunda bile.

Sanırım Dapper’ın en güzel yanı, extension method’lar. Query, QueryAsync falan, async programlamada mükemmel. Benim API’lerimde hep async kullanıyorum, çünkü kullanıcı bekletmek istemiyorum. Mesela bir POST endpoint’inde, veri eklerken.

public async Task<int> AddUserAsync(User user)
{
    using var connection = new NpgsqlConnection(connectionString);
    var sql = "INSERT INTO users (name, email) VALUES (@Name, @Email) RETURNING id;";
    var id = await connection.ExecuteScalarAsync<int>(sql, user);
    return id;
}

Gördüğün gibi, RETURNING ile ID’yi dönüyoruz, PostgreSQL’in özelliği bu. Neticede, API’n hızlı oluyor. Ama dikkat, transaction’lar için connection’ı açık tutman lazım bazen. Ben unuttuğum oldu, veri tutarsızlığı çıktı, proje gecikti. Gerçi o zamanlar Vue frontend’ini de jQuery’den dönüştürüyordum, karmaşa vardı.

Bağlantı String’ini Ayarlama

Şimdi, appsettings.json’a connection string’i koyuyorsun. "Host=localhost;Database=mydb;Username=user;Password=pass" gibi. IConfiguration ile inject ediyorsun controller’a. Basit değil mi? Fakat, production’da environment variable kullan, güvenlik için. Ben Bursa’daki ofisimde, yerel geliştirirken localhost kullanıyorum, ama deploy ederken Azure’a falan koyuyorum.

Açıkçası, Dapper ile PostgreSQL entegrasyonu, benim günlük kodlamamda vazgeçilmez. Eşim bazen kızıyor, "Yine mi kod?" diyor, ama fikir üretmek şart. Hatırlıyorum, bir keresinde, 42 yaşımda olduğum halde, gece yarısı kalkıp bir bug’ı düzelttim. Çocuk uyanmıştı, yanımda yatarken laptop’ta Dapper sorgusu yazdım. Fail oldu tabii, sütun adı yanlış, hata verdi. Sabaha kadar uğraştım, sonunda anladım ki case sensitive PostgreSQL’de. Yani "UserName" yerine "username" yazmam lazımmış. Ne yaparsın işte 🙂

Bu arada, jQuery ile frontend yapıyorsam, API çağrılarında axios kullanıyorum artık, eskiden $.ajax idi. Vue projelerimde de benzer, ama Dapper backend’i hızlandırıyor. Sanırım 3-4 kat fark var performansta, test ettim bir keresinde. Neyse efendim, konuya dönelim.

Dapper’ı kullanırken, mapping için class’larını doğru tanımla. Mesela User class’ında property’ler tablo sütunlarıyla eşleşsin. Eğer alias kullanırsan, "SELECT name AS Name FROM users" diye. Benim deneyimime göre, bu küçük detaylar büyük dertleri önlüyor. Gerçi bazen unutuyorum, debug modunda kırpıyorum kodu.

Fakat, PostgreSQL’in advanced features’ını Dapper ile entegre etmek eğlenceli. Mesela array sorguları, "WHERE id = ANY(@Ids)" gibi. Parametre olarak int[] veriyorsun. Pratik bir örnek, birden fazla user çekmek için. Ben bir rapor API’sinde kullandım, başarılı oldu. O gün öğleden sonra, ailece Osmangazi’ye tura çıktık, ama aklım koddaydı. Eşim fark etti, "Yine mi?" dedi gülerek. Değil mi, kodlama tutkusu böyle bir şey 🙂

Şimdi, error handling’e değineyim biraz. Try-catch blokları koy, connection dispose olsun. Async’te await unutma, yoksa deadlock olur. Benim bir win hikayem var, geçen kış, Uludağ kampından dönünce, bir API’yi Dapper ile yeniden yazdım. Önceki EF versiyonu yavaşlamıştı, 5 saniye sürüyordu sorgu. Dapper’la 200 ms’ye indi, client’lar memnun kaldı. Kahve içip kutladık kendimizi, yani ben 🙂

Evet, ama her şey mükemmel değil. Dapper, complex join’lerde manuel SQL yazdırması lazım, EF gibi otomatik değil. Bana göre, bu trade-off, hız için değer. Tabi, eğer küçük proje ise EF yeterli olur. Bu arada, elektronik devre tasarımı yaparken de benzer, basitlik önemli.

Sanırım buraya bir liste koyayım, temel adımlar için. İlk olarak NuGet paketlerini yükle, Npgsql ve Dapper. Sonra connection string ayarla appsettings’te. En son, repository pattern ile sar, clean code için. Hepsi bu kadar, 10 dakika sürer başlangıç.

Neticede, C# ile Dapper ve PostgreSQL, benim REST API’lerimde standart. Eğer yeni başlıyorsan, NuGet Dapper sayfasında bakabilirsin. Veya Google’da ‘C# Dapper PostgreSQL example’ ara, bol tutorial çıkar. Bir de Microsoft’un docs’unda var, learn.microsoft.com‘da ara .NET connection’lar için. Reddit’te de r/csharp subreddit’inde tartışılıyor, community faydalı.

Açıkçası ben memnunum bu setup’tan, ama bazen MySQL’e dönüyorum projelerde. Hatırlamıyorum tam, bir PHP legacy’si vardı, karışık oldu. Neyse, size tavsiye, pratik yapın, küçük bir API kurun. Aileyle vakit geçirirken bile, fikir not alın. Ben dağcılığa giderken bile, yolda kod düşünüyorum. İyi değil mi? 🙂

Bu arada, geçen ay bir hata yaptım öyleki connection timeout oldu, server’ı restart etmek zorunda kaldım. Değilki sorun büyük, ama sinir bozucu. Sanırım PostgreSQL config’inde max connections artırmam lazımdı. Gerçi şimdi düzelttim.

Sonuç olarak, Dapper ile PostgreSQL, geliştiriciler için harika bir ikili. Benim gibi, aktif kodlama yapanlar için ideal. Deneyin, göreceksiniz. Eğer sorun yaşarsanız, yorum bırakın, yardımcı olurum. İşte böyle, görüşürüz 🙂