Skip to content

Using Retrofit with RxJava

Retrofit is the undisputed best way to consume APIs in Android. As for handling async tasks and callbacks, you’re most probably almost definitely using RxJava or Coroutines. Probably both.

So if you do need to use RxJava and Retrofit, here’s how to do it. No fuss, no bloat. Let’s go!

This is by no means an introduction to either of those, so if you need it, here’s links to my tutorials on RxJava and Retrofit.

Retrofit to RxJava Adapter

def retrofitVersion = 2.8.1

implementation "com.squareup.retrofit2:adapter-rxjava2:${retrofitVersion2}"

It all revolves around a Retrofit call adapter that allows you to consume APIs directly into RxJava Observable types

Retrofit.Builder()
    .addConverterFactory(GsonConverterFactory.create())
    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
    .client(okHttpClient)
    .baseUrl("https://jsonplaceholder.typicode.com/")
    .build()
    .create(PlaceholderApi::class.java)

Build your Retrofit as such, ensuring you call the above addCallAdapterFactory(RxJava2CallAdapterFactory.create()) to add the adapter.

@GET
fun getPosts() : Single<List<Post>>

And in your API interface, you can make your return type an Observable type. It is literally as simple as that.

The type parameter of the observable type does need to correspond to the response, so make sure you’ve set up a data class to model the response (based on what json converter you’re using).

Observable Return Types

Above I used a Single to consume a list of Posts, but how do you know what observable type to use?

Well actually, you can use any of them. In the case of a successful API response, you will get a single item to emit.

This makes Single the most commonly used return type for Retrofit API calls, but for Observable, Flowable, and Maybe, it works as well with having them emit that one item, your response.

Whereas in the case of Completable however, the response body simply gets discarded.

With any of these return types, when the API returns an error response, you will get that error propagated down your observable stream (e.g. via Single.error)