C# İle Httpclient Kullanarak Dış Kaynaklı Veri Çekme İşlemi Nasıl Yapılır?

C# İle Httpclient Kullanarak Dış Kaynaklı Veri Çekme İşlemi Nasıl Yapılır?
C# İle Httpclient Kullanarak Dış Kaynaklı Veri Çekme İşlemi Nasıl Yapılır?

Ön Hazırlık ve Gereksinimler

Bu uygulamayı gerçekleştirmek için bilgisayarınızda .NET 8.0 veya daha güncel bir SDK sürümünün yüklü olması gerekmektedir. Geliştirme ortamı olarak Visual Studio 2022 veya VS Code tercih edebilirsiniz.

  • SDK: .NET 8.0+ (LTS sürümü önerilir)
  • Kütüphane: System.Net.Http (Standart .NET kütüphanesidir)
  • Veri Formatı: JSON (İşlenecek verinin genellikle JSON formatında olduğu varsayılmıştır)

HttpClient sınıfını kullanırken dikkat etmeniz gereken en önemli kural, sınıfın "singleton" (tekil) veya "IHttpClientFactory" aracılığıyla yönetilmesidir. Doğrudan her istekte 'using' bloğu ile oluşturmak, "socket exhaustion" (soket tükenmesi) sorununa yol açabilir.

Temel HttpClient Yapılandırması

HttpClient nesnesini uygulamanızın yaşam döngüsü boyunca tek bir örnek olarak tutmak, performans ve kaynak yönetimi açısından kritiktir. Aşağıdaki örnekte, basit bir veri çekme işlemi için sınıf seviyesinde bir HttpClient tanımlıyoruz.

using System.Net.Http;

public class VeriServisi
{
    private static readonly HttpClient _httpClient = new HttpClient();

    public async Task VeriGetirAsync(string url)
    {
        HttpResponseMessage response = await _httpClient.GetAsync(url);
        response.EnsureSuccessStatusCode();
        string icerik = await response.Content.ReadAsStringAsync();
        Console.WriteLine(icerik);
    }
}

Burada GetAsync metodu, sunucuya bir GET isteği gönderir. EnsureSuccessStatusCode ise dönen yanıtın 2xx aralığında olup olmadığını kontrol eder; aksi takdirde bir hata fırlatır.

API'den Gelen JSON Verisini Nesneye Dönüştürme

Gelen metin tabanlı JSON verisini doğrudan kullanmak yerine, C# nesnelerine (POCO - Plain Old CLR Object) dönüştürmek tip güvenliği sağlar. Bunun için System.Text.Json kütüphanesini kullanacağız.

using System.Text.Json;

public class Kullanici
{
    public int Id { get; set; }
    public string Ad { get; set; }
}

// Kullanımı
var json = await _httpClient.GetStringAsync("https://api.ornek.com/kullanicilar/1");
var kullanici = JsonSerializer.Deserialize(json, new JsonSerializerOptions 
{ 
    PropertyNameCaseInsensitive = true 
});

PropertyNameCaseInsensitive ayarı, JSON içindeki anahtar isimlerinin büyük/küçük harf duyarlılığını ortadan kaldırarak eşleşme hatalarını engeller.

Hata Yönetimi ve Güvenlik Önlemleri

Dış kaynaklı veri çekerken ağ kesintileri, sunucu hataları veya zaman aşımı gibi durumlarla karşılaşmanız kaçınılmazdır. Bu nedenle try-catch blokları ile süreci sarmalamak zorunludur.

try 
{
    var response = await _httpClient.GetAsync("https://api.ornek.com/veri");
    response.EnsureSuccessStatusCode();
}
catch (HttpRequestException e)
{
    Console.WriteLine($"İstek hatası: {e.Message}");
}
catch (TaskCanceledException e)
{
    Console.WriteLine("İstek zaman aşımına uğradı.");
}
Kritik Güvenlik Uyarısı: Dış kaynaktan gelen veriye asla güvenmeyin. Gelen veriyi veritabanına kaydetmeden önce mutlaka doğrulayın (validation) ve SQL injection riskine karşı parametreli sorgular veya ORM (Entity Framework) araçlarını kullanın.

IHttpClientFactory Kullanımı (Önerilen Yöntem)

Modern .NET uygulamalarında HttpClient'ı manuel yönetmek yerine IHttpClientFactory kullanmak en iyi pratiktir. Bu yöntem, DNS değişikliklerini otomatik yönetir ve soket ömrünü optimize eder.

// Program.cs içerisine eklenir
builder.Services.AddHttpClient("DısServis", client =>
{
    client.BaseAddress = new Uri("https://api.ornek.com/");
    client.DefaultRequestHeaders.Add("Accept", "application/json");
});

// Kullanımı
public class Servis(IHttpClientFactory httpClientFactory)
{
    public async Task VeriCek()
    {
        var client = httpClientFactory.CreateClient("DısServis");
        var sonuc = await client.GetAsync("endpoint");
    }
}
Yöntem Avantajı Dezavantajı
Static HttpClient Basit kurulum DNS güncellemelerini algılamaz
IHttpClientFactory DNS yönetimi, ölçeklenebilir Dependency Injection gerektirir

Sıkça Sorulan Sorular

HttpClient ile POST isteği nasıl atılır?

PostAsync metodunu kullanarak içeriği JsonContent.Create(nesne) ile gönderebilirsiniz.

Neden "using" bloğu içinde HttpClient kullanmamalıyım?

Her istekte yeni bir HttpClient oluşturmak, bağlantı kapandıktan sonra soketlerin "TIME_WAIT" durumunda kalmasına ve sistemin soket kaynaklarının tükenmesine neden olur.

API'ye nasıl token (Yetkilendirme) eklerim?

client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "tokeniniz"); satırını kullanarak isteklerinize yetkilendirme başlığı ekleyebilirsiniz.

Zaman aşımı süresini nasıl ayarlarım?

client.Timeout = TimeSpan.FromSeconds(30); özelliği ile isteğin maksimum ne kadar süreceğini belirleyebilirsiniz.

Veri çekerken oluşan karakter kodlama sorunlarını nasıl çözerim?

Genellikle UTF-8 varsayılan olarak gelir ancak farklı bir kodlama varsa response.Content.ReadAsStringAsync() yerine ReadAsByteArrayAsync() kullanarak veriyi manuel olarak decode edebilirsiniz.

Sorumluluk Reddi: Bu makaledeki kod örnekleri eğitim amaçlıdır. Üretim ortamında kullanacağınız API anahtarlarını asla kod içerisinde hard-coded (sabit) olarak bırakmayın; "User Secrets" veya "Azure Key Vault" gibi güvenli konfigürasyon araçlarını kullanın.

HttpClient Performansını Optimize Etme ve İleri İpuçları

HttpClient kullanımı sırasında performans darboğazlarını aşmak ve uygulamanın ölçeklenebilirliğini artırmak için sadece IHttpClientFactory kullanmak yeterli olmayabilir. Özellikle yüksek trafikli uygulamalarda, bağlantı havuzu yönetimi ve veri işleme süreçlerinde dikkat edilmesi gereken kritik noktalar bulunmaktadır.

Bağlantı Havuzu ve Socket Tükenmesini Önleme

HttpClient, arka planda HttpClientHandler üzerinden TCP bağlantılarını yönetir. Eğer bağlantılar doğru kapatılmazsa veya çok hızlı bir şekilde yeni istemciler oluşturulursa "Socket Exhaustion" (Soket Tükenmesi) hatası alırsınız. Bunu engellemek için bağlantı ömrünü sınırlayan PooledConnectionLifetime özelliğini yapılandırmanız önerilir.


services.AddHttpClient("MyClient", client => {
    client.BaseAddress = new Uri("https://api.ornek.com/");
})
.SetHandlerLifetime(TimeSpan.FromMinutes(5)) // Handler'ın yenilenme süresi
.ConfigurePrimaryHttpMessageHandler(() => new SocketsHttpHandler {
    PooledConnectionLifetime = TimeSpan.FromMinutes(2) // Bağlantı havuzu ömrü
});

Büyük Veri Setleri İçin Stream Kullanımı

API'den gelen veriler çok büyükse, ReadAsStringAsync() metodunu kullanmak tüm veriyi belleğe (RAM) yükler. Bu durum, özellikle düşük kaynaklı sunucularda OutOfMemoryException hatalarına yol açabilir. Bunun yerine veriyi stream olarak okuyup işlemek çok daha performanslıdır.


using var response = await _httpClient.GetAsync("api/buyuk-veri", HttpCompletionOption.ResponseHeadersRead);
response.EnsureSuccessStatusCode();

using var stream = await response.Content.ReadAsStreamAsync();
var veriler = await JsonSerializer.DeserializeAsync(stream);

HttpClient İsteklerini Birim Test (Unit Test) ile Doğrulama

Dış servislere bağımlı kodları test etmek zordur çünkü gerçek API'ye her testte istek atmak hem yavaştır hem de API limitlerinizi tüketebilir. Bu sorunu çözmek için HttpMessageHandler sınıfını "mock"layarak (taklit ederek) gerçek bir ağ isteği yapmadan testlerinizi gerçekleştirebilirsiniz.

Moq ve DelegatingHandler Kullanımı

Gerçek bir HTTP çağrısı yapmadan, API'den dönen yanıtı simüle etmek için aşağıdaki gibi bir yapı kurabilirsiniz:


public class MockHttpMessageHandler : HttpMessageHandler
{
    protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        return new HttpResponseMessage
        {
            StatusCode = HttpStatusCode.OK,
            Content = new StringContent("{\"id\": 1, \"name\": \"Test Verisi\"}")
        };
    }
}

// Test içerisinde kullanımı:
var handler = new MockHttpMessageHandler();
var httpClient = new HttpClient(handler);
var service = new VeriServisi(httpClient);

Bu yöntemle, API'niz kapalı olsa bile kodunuzun mantıksal olarak doğru çalışıp çalışmadığını, hata durumlarını (404, 500 gibi) nasıl yönettiğini güvenle test edebilirsiniz.

Sonuç

C# ile HttpClient kullanarak dış kaynaklı veri çekme işlemi, doğru yapılandırıldığında uygulamanızın dış dünya ile en güvenli ve hızlı iletişim yoludur. Bu rehberde öğrendiğiniz IHttpClientFactory kullanımı ve hata yönetimi stratejileri, profesyonel projelerinizin temel taşlarını oluşturacaktır. Bir sonraki adım olarak, çektiğiniz verileri veritabanına aktarmak için Entity Framework Core entegrasyonunu incelemenizi öneririm.

Bu yazıya tepkinizi paylaşın:
Selin Korkmaz

Kendin yap (DIY) projeleri ve sürdürülebilir yaşam ipuçları üzerine odaklanıyorum. Okuyucularıma bütçe dostu ve yaratıcı çözüm önerileri sunmaktan keyif alıyorum.

Yorumlar (0)

Yorum Yaz