Retrofit, Android Developerlar arasında sıklıkla kullanılan bir networking kütüphanesidir. Retrofit’in bu kadar popüler olmasında REST API’lara kolaylıkla erişebilme, test edilebilir ve kolay kullanımı etkendir.
Bu yazıda Retrofit’in nasıl kullanılacağından bahsetmeye çalışacağım.
Kurulum
Önceliklebuild.gradle
dosyasına alttaki gibi dependency ekliyoruz.
1 |
compile 'com.squareup.retrofit2:retrofit:2.4.0' |
JSON çıktılarını POJO classlara dönüştürmek için GSON kullanacağız. Retrofit bize GSON için ayrı bir converter kütüphanesi sağlıyor. Bunu da aynı şekilde dependecy lere ekliyoruz.
1 |
compile 'com.squareup.retrofit2:converter-gson:2.3.0' |
Network istekleri yapacağımız için projemizde INTERNET iznini de almamız gerekiyor. Onun için Manifest dosyasına alttaki izni ekliyoruz.
1 |
<uses-permission android:name="android.permission.INTERNET"/> |
Artık Retrofit kullanmaya başlayabiliriz.
Kullanım
Yapacağımız örnekte fake API çağrıları yapabilmemizi sağlayan JSONPlaceholder API kullanacağız.
Retrofit nesnesini içerisinde oluşturacağımızNetworkService
adında bir class oluşturuyoruz.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public class NetworkService { private static NetworkService mInstance; private static final String BASE_URL = "https://jsonplaceholder.typicode.com"; private Retrofit mRetrofit; private NetworkService() { mRetrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .build(); } public static NetworkService getInstance() { if (mInstance == null) { mInstance = new NetworkService(); } return mInstance; } } |
baseUrl()
metoduna üzerinde çalışağımız API adresini yazdık.
addConverterFactory()
metodu içerisinde üstte convert için dahil ettiğimiz kütüphanenin GsonConverterFactory.create()
metodunu ekledik. Burada farklı converter kütüphaneleri kullanılabilir. Örneğin converter olarak Moshi kullanıyorsanız bunun gerekli converter kütüphanesini dahil edip addConverterFactory()
metoduna parametre olarak vereceksiniz.
getInstance()
metodunda ise oluşturduğumuz retrofit nesnesini döndüren bir yapı kurduk. Burada singleton design pattern kullandık. Her seferinde yeni bir nesne oluşturmak yerine bir kere oluşturup sonrasında var olan nesneyi çağırdık.
API’dan okuyacağımız verileri POJO classlara aktarmamız gerekiyor.
Kullanacağımız API’daposts/5
endpointe istek attığımızda alttaki gibi bir istek geliyor.
1 2 3 4 5 6 |
{ userId: 1, id: 5, title: "nesciunt quas odio", body: "repudiandae veniam quaerat sunt sed alias aut fugiat sit autem sed est voluptatem omnis possimus esse voluptatibus quis est aut tenetur dolor neque" } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
public class Post { @SerializedName("userId") private int userId; @SerializedName("id") private int id; @SerializedName("title") private String title; @SerializedName("body") private String body; public int getUserId() { return userId; } public void setUserId(int userId) { this.userId = userId; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getBody() { return body; } public void setBody(String body) { this.body = body; } } |
@SerializedName
annotation kullanarak alıp propertylere atadık ve onların getter, setter metodlarını yazdık.
Şimdi kullanacağımız API isteklerini yazacağımız bir arayüz oluşturacağız. Bunu da ApiInterface
olarak adlandıralım.
1 2 3 |
public interface ApiInterface { } |
Bu arayüzün içine istek türleri (GET, POST, PUT, DELETE) ile birlikte endpointleri ve gerekli parametreleri ekleyeceğiz.
Örneğin bizim istek atacağımız endpointposts/5
şeklinde olacak. Burada bize id ye göre 1 tane post objesi döndürüyor. Buna uygun olarak ApiInterface
arayüzünü yazalım.
1 2 3 4 5 |
public interface ApiInterface { @GET("/posts/{id}") public Call<Post> getPostWithID(@Path("id") int id); } |
@GET
annotation kullandık ve buna parametre olarak endpointi yazdık. Dikkat ederseniz id değeri değişken olabildiği için bu kısmı süslü parantezler içinde yazdık ve alttaki metoda bunu @Path
annotation kullanarak parametre olarak verdik.
Dönüş değeri olarak yine bir Retrofit classı olan Call
arayüzünü kullanarak buna yazdığımız Post classını Call<Post>
şeklinde verdik.
Şimdi Retrofit’ten bize ApiInterface arayüzümüzün oluşturulmasını isteyeceğiz. Bunun için NetworkService classını güncellememiz gerekiyor.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
public class NetworkService { private static NetworkService mInstance; private static final String BASE_URL = "https://jsonplaceholder.typicode.com"; private Retrofit mRetrofit; private NetworkService() { mRetrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .build(); } public static NetworkService getInstance() { if (mInstance == null) { mInstance = new NetworkService(); } return mInstance; } public ApiInterface getJSONApi() { return mRetrofit.create(ApiInterface.class); } } |
Gördüğünüz gibi classın en altında getJSONApi()
metodu ile bu işlemi gerçekleştirdik.
Şimdi son aşama olarak yazdığımız api isteklerini nerede yapacaksak onu orada çağırmamız gerekiyor. Örneğin bir activity içerisinde alltaki gibi bir çağrım yapabiliriz.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
NetworkService.getInstance() .getJSONApi() .getPostWithID(1) .enqueue(new Callback<Post>() { @Override public void onResponse(@NonNull Call<Post> call, @NonNull Response<Post> response) { Post post = response.body(); // post nesnesi ile isteğiniz veriyi çağırabilirsiniz. Örneğin post.getTitle(), post.getBody() vs. } @Override public void onFailure(@NonNull Call<Post> call, @NonNull Throwable t) { t.printStackTrace(); } }); |
Burada enqueue
metodu ile yeni bir CallBack<Post>
objesi oluşturduk. Bunun içerisinde 2 adet metod override ediliyor. onResponse
request başarılı olduysa, onFailure
ise herhangi bir hata olduysa çalışır. onResponse
parametlerinden Response<Post>
içerisinde gelen değerleri barındırır.
Aynı API üzerinden farklı istekler yapalım. Örneğin /posts
endpointini kullanarak bütün postları alalım. Bunun için arayüzde yazmamız gereken kod alttaki gibi olacaktır.
1 2 |
@GET("/posts") public Call<List<Post>> getAllPosts(); |
Ya da /posts?userId=2
şeklinde bir çağrım yapmak istersek o zaman isteğimiz şöyle olacaktır.
1 2 |
@GET("/posts") public Call<List<Post>> getPostByUserId(@Query("userId") int id); |
Burada endpointe userId şeklinde query eklediğimiz için queryi, Retrofit’in @Query
annotationa query ile aynı isimde parametre olarak veriyoruz.
POST işlemi yapmak istenildiğinde ise kodumuz alttaki gibi olacaktır.
1 2 |
@POST("/posts") public Call<Post> postData(@Body Post data); |
Burada @Body
annotation ile post edilecek verileri direk olarak obje şeklinde gönderebiliyoruz.
Retrofit kullanımı basit olarak bu şekilde. Eğer daha fazla bilgi almak istiyorsanız retrofit dökümantasyona göz atabilirsiniz.
https://square.github.io/retrofit/