HttpClient’a Veda Refit’e Merhaba

Mesut Solak
Berkut Teknoloji
Published in
4 min readFeb 16, 2023

🌟 Genel Bakış

Öncelikle başlığı ilgi çekmek için yazdığımı kabul ediyorum 😁 Refit kullanıyor olmamız tam olarak HttpClient sınıfına veda ettiğimiz anlamına gelmemektedir.Refit , uygulamayı çalıştırdığımızda HttpClient sınıfını kullanmak için yazmış olduğumuz statik işlemleri , belirlemiş olduğumuz interface ismine uygun olarak , kendi tarafında bir somut sınıf oluşturarak gerçekleştirir. Refit’in kendi içerisinde oluşturmuş olduğu somut sınıfı klasör yapısında görememekteyiz.Visual Studio üzerinde somut sınıfı görebilmek için , uygulamayı çalıştırıp ilgili API’ye istek de bulunduğumuz yerlerde F11 ile ilerlememiz gerekmektedir.Refit ile API’ye istek de bulunmak için HttpClient sınıfını yazmasak bile ihtiyacımız olduğunu öğrendikten sonra daha detaylı bilgiyi aşağıda bulabiliriz 🚀

🤔 Nedir ?

Refit , HttpClient yerine interface yardımıyla Rest API’lere istek atmamızı kolaylaştıran bir kütüphanedir.Refit , Android tarafında kullanılan Retrofit isimli kütüphaneden esinlenerek hazırlanmıştır.

Refit

🤔 Hangi Platformlarda Kullanılabilir ?

Refit, .NET ve Xamarin platformlarında kullanılabilir.

🤔 Faydaları Nelerdir ?

  • Refit , API çağrılarını yaparken kullanılan nesne modellerini otomatik olarak tanımlar ve serileştirir.
  • Refit , API ile çalışmak için gerekli olan kod miktarını azaltır.
  • Refit , kodun okunaklılığını , anlaşılırlığını ve test edilebilirliğini arttırır.
  • Refit , kodun bakımını ve yönetebilirliğini kolaylaştırır.
  • Refit , geliştiricilerin API ile çalışmak için daha az zaman harcamalarına olanak tanır.

🤔 Nasıl Kurulur ?

Refit kütüphanesini kullanabilmek için ilk önce ilgili katmana nuget kurulumlarını yapmamız gerekmektedir.Nuget kurulumu yapabilmek için ilgili katmana sağ tıklayıp -> Manage Nuget Packages dememiz gerekmektedir.

Gerekli Olan Nugetler

Açılan pencerede yukarıda kırmızı çerçeveye alınmış olan nuget paketlerinin kurulması gerekmektedir.”Refit.Xml” nugetini Xml ile ilgili işlemimiz olduğunda yüklememiz daha doğru olacaktır.

Package Manager Console üzerinden aşağıdaki kod bloğunu teker teker çalıştırarak kurulum işlemizi gerçekleştirebiliriz.Visual Studio üzerinden Package Manager Console penceresine ulaşabilmek için View -> Other Windows -> Package Manager Console yolunu izlememiz gerekir.

dotnet add package refit
dotnet add package refit.httpclientfactory
dotnet add package refit.newtonsoft.json
dotnet add package refit.xml

🤔 Nasıl Ayarlanır ?

Kurulum işlemlerimizden sonra .NET 6 projemiz için environment tanımlaması yapmamız gerekmektedir.Biz bu örnek için sadece appsettings.Localhost.json dosyası için tanımlama yapacağız.

"UserApi": {
"BaseAddress": "https://localhost:44353/api/"
}

Environment tanımlaması yaptıktan sonra Refit’i kullanabilmek için aşağıdaki metodu ilgili katmanımızda uygun yere ekliyoruz.En çok bilinen ve sıklıkla duyulan yazılım geliştirme prensiplerinden DRY (Dont Repeat Yourself) yani kendini tekrar etme prensibine uygun olarak dinamik bir metot hazırlanmıştır.İlgili metot sayesinde Refit’i entegre etme ihtiyaç duyduğumuz her yerde kolaylıkla kullanabiliriz.

public static IServiceCollection AddRefit<TRefitClient, THandler>(this IServiceCollection services, string configurationKey) where TRefitClient: class where THandler : DelegatingHandler
{
var configuration = services.BuildServiceProvider().GetService<IConfiguration>();

services.AddRefitClient<TRefitClient>(new RefitSettings
{
ContentSerializer = new NewtonsoftJsonContentSerializer(new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
})
}).ConfigureHttpClient(httpClient => httpClient.BaseAddress = new Uri(configuration[configurationKey]))
.AddHttpMessageHandler<THandler>();

services.AddScoped<THandler>();

return services;
}

Yukarıdaki metodu açıklamam gerekirse ilk önce genel tip olarak aldığımız TRefitClient sayesinde API’miz için oluşturduğumuz interface değerini alırken THandler sayesinde ise oluşturduğumuz DelegatingHandler değerini alabilmekteyiz. (Interceptor gibi düşünebiliriz)

Genel tipleri tam anlamıyla kullanabilmek için kısıtlayıcı tanımlaması yapmamız gerekir.Ek olarak environment tanımlaması yaptığımız değeri alabilmek için configurationKey parametresini kullanmaktayız.

IServiceCollection interface’i sayesinde IConfiguration çağırımı yaparken RefitSettings sınıfı ile Refit ayarlamalarını gerçekleştirebiliriz.

Örnek olarak kullanıcının giriş yapma senaryosunu ele alabiliriz.

API için oluşturduğumuz interface ;

public interface IUserApi
{
[Post("/User/Login")]
Task<UserInfoResponseModel> LoginAsync(LoginModel loginModel);
}

LoginAsync metoduyla kullanıcının giriş işlemini gerçekleştirebilmekteyiz.

public class AuthHeaderHandler : DelegatingHandler
{
private readonly IHttpHelper _httpHelper;

public AuthHeaderHandler(IHttpHelper httpHelper)
{
_httpHelper = httpHelper;
}

protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var userInfo = _httpHelper.GetSession<UserInfoResponseModel>(SessionConstants.UserInfoKey);

if (userInfo is not null)
{
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", userInfo.Token);
}

return await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
}
}

AuthHeaderHandler isminde oluşturduğum DelegatingHandler sayesinde yapılan her istekde manuel olarak başlıkta token göndermeme gerek kalmayacaktır çünkü AuthHeaderHandler sınıfı token gönderimini otomatik hale getirecektir.

Son olarak oluşturmuş olduğumuz ayarları AddRefit metodunu kullanarak Startup.cs içerisine eklememiz gerekir.

public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddRefit<IUserApi, AuthHeaderHandler>(Constants.UserApiBaseAddress);
}
}

Klasör yapısına önem verenler için aşağıdaki şekilde oluşturabiliriz.

Klasör Yapısı

🤔 Nasıl Kullanılır ?

API metotlarını kullanabilmek için oluşturduğumuz IUserApi interface’nin normal interface kullanımından farkı yoktur.

public class UserService : IUserService
{
private readonly IUserApi _userApi;

public UserService(IUserApi userApi)
{
_userApi = userApi;
}

public async Task<UserInfoResponseModel> LoginAsync(LoginModel loginModel)
{
return await _userApi.LoginAsync(loginModel);
}
}

Proje içerisinde kullanıcı işlemlerini gerçekleştirmek için oluşturduğumuz UserService sınıfın yapıcı metodunda IUserApi değerini alabilmekteyiz.

Bu makalede Refit’in ne iş yaptığını , faydalarını ve nasıl kullanılabileceğin den bahsettik.Refit’in istek gönderim şekillerini , hata yönetimini ve ayarları hakkında daha detaylı bilgiyi github adresinden bulabilirsiniz.

https://github.com/reactiveui/refit

Makalemi zaman ayırıp okuduğunuz için teşekkür ederim 😊
Bir sonraki yazıda görüşmek üzere.Esen kalın.. 👋

Son

--

--