Erhan Ballıeker

Resilient Network Services Bölüm 2 – REFIT – 2

Selamlar. Bir önceki yazımda Resilient Network Services için kullanacağımız kütüphanelerden olan Refit için incelemelere başlamıştık. Bu yazımızda bunu tamamlayıp bir sonraki yazılarımız da diğer kütüphanelere değineceğiz.

Önceki yazımızı da Refit ile GET ve POST işlemlerine bakmıştık. Farklı durumlar için incelemiş örnekler göstermiştik. Okumadıysanız bu yazıdan önce Refit ile ilgili ilk yazımı okumanızı tavsiye ederim.

Bu yazımızda refit ile request in Header, Authorization, Multpipart upload, response ve error handling kısımlarına değineceğiz.

Static ve Dynamic Header Tanımlamaları

Static bir header ı refit interface imize ister tüm Interface bazında istersek de metod bazında istediğimiz kadar eklemek için, kullanacağımız yöntem Headers attribute u olucaktır. Örnek olarak;

[Headers("Content-Type: application/json")]
public interface IGitHubApi
{
    [Get("/users/{user}")]
    Task<User> GetUser(string user);
    
    [Post("/users/new")]
    Task CreateUser([Body] User user);
}

şeklinde global olarak(yani interface içerisindeki herbir metod için çalışacak şekilde) tanımlayabiliriz. Ya da aynı attribute u sadece istediğimiz metodun üzerine de yerleştirebiliriz.

Bu zaten çok önemli bir durum değil çok fazla da ihtiyacımız olucak değil, ama kullanımını yine de bilmekte fayda var. Daha önemlisi dinamik olarak değişecek olan headerlar için nasıl bir yöntem kullanacağız. Örneğin her bir request için Authorization header ı göndermek istiyorum. Bu header da dinamil bir header olucak tabii ki. Bunun için ise şu şekilde ilerliyoruz.

[Get("/users/{user}")]
Task<User> GetUser(string user, [Header("Authorization")] string authorization);

var user = await GetUser("erhanballieker", "mytoken.....");

Yukarıda göreceğiniz gibi interface içerisinde tanımlamış olduğumuz metodun header olarak göndermek istediğimiz parametresinin başında Header attribute u nu kullanıp parametre olarak header ın adının ne olacağını veriyoruz(örnekte “Auhtorization” dedik).  bu metodu kullanırken de 2. satırda yazmış olduğumuz gibi “mytoken…” olan paraametre request in Headerlarına Authorization header ı olarak ekleniyor olacaktır.

Refit ile request in headerlerı ile oynamakta bu kdar basit hale gelmiş durumda. Son olarak header lar kısmını bitirmeden şundan bahsedelim, Headerları tanımalamak için 3 yer gördük interface üzerinde, metod üzerinde ve parametre üzerinde, peki bunlardan hangisi daha öncelikli. yani aynı header ismi ile üçünede bir değer koysak hangisi kazanır,

öncelik sırası şöyle;

  1. Parametre başına tanımlanan değer.
  2. metod başına tanımlanan değer
  3. interface seviyesinde tanımlanan değer.

yani aşağıdaki gibi bir örnek için request e “MyHeader” ismiyle eklenecek olan değer parametre olarak verilen değerinki olucaktır.

[Headers("MyHeader: MyHeaderInterface")]
public interface IGithubApi
{
   [Headers("MyHeader: MyHeaderMetod")]
   public Task GetUser(string username, [Header("MyHeader")] string parameter = "actaulValue"]);
}

Multipart Upload

[Multipart] attribute u ile işaretlemiş olduğumuz metodlar multipart content type olarak submit olucaklar.desteklenen multipart methods parametre tipleri aşağıdaki gibidir.

  • string (parameter name will be used as name and string value as value)
  • byte array
  • Stream
  • FileInfo

parametrenin adı multipart datanın adı olarak set edilir default olarak. Yine AliasAs kullnarak bu durumu değiştirebiliriz.

public interface ISomeApi
{
    [Multipart]
    [Post("/users/{id}/photo")]
    Task UploadPhoto(int id, [AliasAs("myPhoto")] StreamPart stream);
}

Bu metoda multipart olarak data göndermek için aşağıdaki şekilde kullanabiliriz.

someApiInstance.UploadPhoto(id, new StreamPart(myPhotoStream, "photo.jpg", "image/jpeg"));

Response Handling

Refrofitin aksine Refit te synchronous api call yapamıyoruz. Tüm requestler Task ile veya IObservable ile async olarak yapılmalı.  Generic parametresi verilmemiş bir Task olarak metodu tanımlamak sadece request in başarılı tamamlanıp tamamlanamadığını bize söyler o kadar.

[Post("/users/new")]
Task CreateUser([Body] User user);


await CreateUser(someUser);

Eğer parametre tipi HttpResponseMessage veya string ise content olduğu gibi geriye döner. Task objesi içerisine bir model verirsek dönen response Refit tarafından otomatik olarak istediğimi model e deserialize edilir ve o şekilde bize ulaşır.

//response string olarak geri döner. (ham json data gibi)
[Get("/users/{user}")]
Task<string> GetUser(string user);

//tüm response IObservable olarak Reactive Extensionlar ile kullanıma hazır şekilde döner.
[Get("/users/{user}")]
IObservable<HttpResponseMessage> GetUser(string user);

//response verilen generic tipe dönüştürülüp bize ulaşır.
[Get("/users/{user}")]
Task<User> GetUser(string user);

Genel olarak bir api ile haberleşirken herhangi bir modelin CRUD işlemlerini yapacak endpoint e request atmamız gerekecektir. Bunun için her model için ayrı ayrı interface veya metodlar tanımlamak yerine, Refit bize generic olarak interfaceleri tanımalama imkanı da sunuyor.  Aşağıdaki örnekte ki gibi tüm Refit interface imizi generic bir parametre tipine bağlı olarakta tanımlayabiliriz.

public interface ICrudApi<T, in TKey> where T : class
{
    [Post("")]
    Task<T> Create([Body] T payload);

    [Get("")]
    Task<List<T>> ReadAll();

    [Get("/{key}")]
    Task<T> ReadOne(TKey key);

    [Put("/{key}")]
    Task Update(TKey key, [Body]T payload);

    [Delete("/{key}")]
    Task Delete(TKey key);
}

Yukarıda göreceğiniz gibi projemizde ki herbir modelin crud işlemleri için bu şekilde bir Refit interface i tanımlayabiliriz. Herbir request için ilgili HttpVerb ü verilip, Task içerisinide geri dönen response un deseriazlize edilecek generic type veriliyor.

Son iki yazımızda Refit e oldukça değinmiş incelemiş olduk. Bir sonraki yazımızda Resilient Network Services serimizde Fusillade in kullanımı ile devam ediyor olacağız.

Görüşmek üzere.

Bir Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Connecting to %s

%d blogcu bunu beğendi: