Retrofit has become a very familiar name in the Android ecosystem for a very useful library. One that turns your HTTP API into a Java (or Kotlin) interface. In layman’s terms, it makes loading APIs into POJOs ridiculously simple and we’re going to be following that trend as we learn how to implement that.
How it works is you have a model class which is a POJO. Retrofit loads in the API directly into your model class so the result of your API call is an instance or a list of your model class.
This tutorial’s going to just scrape the surface of Retrofit, fitting if you don’t know a single thing about how to implement it yet. No wasting time or brain power with authentication and all that jargain just yet.
For this tutorial, I will be using the JSON Placeholder API, though if you want to reap the most benefit out of this tutorial, I suggest you try it out using any other popular free APIs like OpenWeatherMap or OMDb.
https://jsonplaceholder.typicode.com/posts
This is the URL for the API I’ll be using and it’ll return a result like this:
{ "userId": 1, "id": 1, "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto" }, { "userId": 1, "id": 2, "title": "qui est esse", "body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla" }
Import the Dependencies
Add these dependencies to your app/build.gradle file.
implementation 'com.squareup.retrofit2:converter-gson:2.1.0' implementation 'com.squareup.retrofit2:retrofit:2.1.0'
Defining the Model
We want to set up our model as a POJO (Plain Old Java Object). What this essentially means is a class with nothing but their variables and their getter/setter methods. In Kotlin, getter/setters are automatically defined so we don’t need to write them ourselves.
class Post { var userId: Int = 0 var id: Int = 0 var title: String = "" @SerializedName("body") var text: String = "" }
You want to match the variable names to the API fields. If you want to put a more fitting name for the variable in your app than the name in the API, annotate it with SerializedName(“apifield”) to match the variable to the API field.
Write the Interface
Create a new interface where you will place all your Retrofit calls.
interface JsonPlaceHolderApi { @GET("posts") fun getPosts(): Call<List<Post>> }
Each call is a function annotated with @GET(“urlextension”) or @POST(“urlextension”), depending on the action you’re performing.
Build the Retrofit
A Retrofit is the object that makes all your Retrofit calls. In your main code, create a retrofit object using the builder, defining the Base URL of your APIs and the Converter Factory as the GsonConverterFactory.
val retrofit = Retrofit.Builder() .baseUrl("https://jsonplaceholder.typicode.com/") .addConverterFactory(GsonConverterFactory.create()) .build() val jsonPlaceHolderApi = retrofit.create(JsonPlaceHolderApi::class.java)
Then get an instance of your API Interface by using retrofit.create.
Make the Call
Just like that, we can use the API instance to make our Retrofit calls!
val call = jsonPlaceHolderApi.getPosts() call.enqueue(object: Callback<List<Post>> { override fun onResponse(call: Call<List<Post>>?, response: Response<List<Post>>?) { } override fun onFailure(call: Call<List<Post>>?, t: Throwable?) { } })
Use a callback to get the results of your API call and you’ve basically got your data!
Spice it up with RxJava
I am a huge fan of RxJava for its huge multitude of benefits for pretty much any app, and it works excellently with Retrofit. Strengthen their interactions by adding this dependency as well as the RxJava and RxAndroid dependencies if you haven’t already got them in.
implementation 'io.reactivex.rxjava2:rxjava:2.0.2' implementation 'io.reactivex.rxjava2:rxandroid:2.0.1' implementation 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
Where you build your Retrofit object, define the CallAdapterFactory like so, otherwise your app will crash.
val retrofit = Retrofit.Builder() .baseUrl("https://jsonplaceholder.typicode.com/") .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build()
Change your interface to return an Observable instead of a Call.
@GET("posts") fun getPosts(): Observable<List<Post>>
Then finally, make the call as an observable
val observable = jsonPlaceHolderApi.getPosts() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe { posts -> ... }