Zoom Webinar: Learn and enhance your TypeScript skills | 28th March 2023 | 10 AM PST [10:30 PM IST] Register here
Education

Retrofit: The Easiest Way to Call REST API in Android

logo

DhiWise

July 8, 2021
image
Author
logo

DhiWise

{
July 8, 2021
}

Traditionally, performing networking tasks in Android was a nightmare. Communicating with the server by placing network calls involves lots of effort as developers often preferred to make use of the main thread to perform networking tasks.
It causes the Android application to slow down or sometimes freeze affecting user experience. 
However today they have a whole range of REST client libraries that speed up app development by reducing the app networking efforts. 
In 2013, Google developed Volly, which can access REST APIs. Still, there was room for improvement thus Square introduced Retrofit- A powerful library to interact with REST API. 

A brief introduction to Retrofit 

Retrofit 2 is the type-safe HTTP client, built by Square Inc for Java and Kotlin applications that simplify authenticating and interacting with REST APIs and sending network requests with OkHttp. 
Retrofit is a very powerful library that can make the most problematic API easy to use. Retrofit 2 makes networking easier by offering an abstraction layer over the HTTP calls and automatically generating complex code files.
It is designed to simplify endpoint declaration i.e how requests are created and sent to the server and how responses are read and parsed. It naturally serialises and deserialises the JSON reactions and directly returns POJO (Plain Old Java Objects).

Other than the above it is used to perform the following tasks:

  • It changes the IP addresses if there is any connection failure.
  • Caches server response to avoid sending duplicate requests.
  • Retrofit pools connections to reduce latency.

Advantages of Retrofit

  • Supports both synchronous and asynchronous requests.
  • Support request cancellation.
  • Have a smoother learning curve.
  • Allows direct communication with the web server.
  • Supports post requests, multipart uploads, dynamic URLs, and convertors.
  • Improves app performance and safety.

The only disadvantage with Retrofit, it doesn’t provide support for image loading from the server. In that case, other libraries such as Glide, Picasso, or Fresco can be used.

Implementing Retrofit with Kotlin

Here will use Retrofit, Kotlin, and RxJava to demonstrate how it simplifies REST API interaction in Android applications. We will make use of the Github API and a list of Java developers in Lagos.Before you begin implementation, make sure you have the Kotlin development environment ready. Kotlin is supported natively in Android Studio 3.0 and later.

  1. Add Dependencies

To use Retrofit in your application, you need to add some dependencies to your app module build.gradle file.

dependencies {
    // retrofit
    compile "com.squareup.retrofit2:retrofit:2.3.0"
    compile "com.squareup.retrofit2:adapter-rxjava2:2.3.0"
    compile "com.squareup.retrofit2:converter-gson:2.3.0"

    // rxandroid
    compile "io.reactivex.rxjava2:rxandroid:2.0.1"
}

In the above code snippet, the first dependency is the Retrofit dependency. The second one is for the RxJava2 adapter to make calls reactive through the set of interfaces and methods. The third is the GSON converter that handles data serialisation and deserialisation of request and response bodies to and from JSON format. The final dependency is RxAndroid, it is an extension to RxJava2 it provides a scheduler for running code in the Android application's main thread.

Retrofit 2 already includes the OkHttp dependency.  If you wish to use a separate OkHttp dependency, exclude it from Retrofit2 as:

// exclude Retrofit’s OkHttp dependency module and define your own // module 
compile ("com.squareup.retrofit2:retrofit:2.1.0") { 
import exclude module: 'okhttp' } 
compile "com.google.code.gson:gson:2.6.2" 
compile "com.squareup.retrofit2:converter-gson:2.1.0" 
compile "com.squareup.okhttp3:logging-interceptor:3.4.1"
compile "com.squareup.okhttp3:okhttps:3.4.1"

The logging interceptor generates a log string for the entire response.  There are also other converters to parse Json to the required type, some of which are, 

  1. Jackson: com.squareup.retrofit2:converter-jackson:2.1.0
  2. Moshi: com.squareup.retrofit2:converter-moshi:2.1.0
  3. Protobuf: com.squareup.retrofit2:converter-protobuf:2.1.0
  4. Wire: com.squareup.retrofit2:converter-wire:2.1.0
  5. Simple XML: com.squareup.retrofit2:converter-simplexml:2.1.0

Add the permission to access the internet in the AndroidManifest.xml file.

  1. Creating Data Classes for Resources

The next step is to create data classes with Plain Old Java Object that will represent the response of API calls. In Kotlin, data classes are designed for the classes that hold the data. 
To define a data class,  we simply add a data keyword before the class name. Further, the Kotlin compiler assists in automatically implementing methods on a class, resulting in even shorter code.

// Data class in Kotlin
data class User(
        val login: String,
        val id: Long,
        val url: String,
        val html_url: String,
        val followers_url: String,
        val following_url: String,
        val starred_url: String,
        val gists_url: String,
        val type: String,
        val score: Int
)

In Kotlin, we can create a single search response file like getSearchResponse.kt. The final search response class will contain all the related data classes. 

// Data class in Kotlin with final search response class
data class User(
        val login: String,
        val id: Long,
        val url: String,
        val html_url: String,
        val followers_url: String,
        val following_url: String,
        val starred_url: String,
        val gists_url: String,
        val type: String,
        val score: Int
)
data class Result (val total_count: Int, val incomplete_results: Boolean, val items: List)
  1. Create an API service Interface

The following step is to design an API interface that will be used to send requests and receive responses via retrofit.

GithubApiService.kt

interface GithubApiService {

    @GET("search/users")
    fun search(@Query("q") query: String,
               @Query("page") page: Int,
               @Query("per_page") perPage: Int): Observable

    /*
     * Companion object to create the GithubApiService
     */
    companion object Factory {
        fun create(): GithubApiService {
            val retrofit = Retrofit.Builder()
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .addConverterFactory(GsonConverterFactory.create())
                    .baseUrl("https://api.github.com/")
                    .build()

            return retrofit.create(GithubApiService::class.java);
        }
    }
}

The interface and the factory class can be used as,

We didn’t have to use the name of the companion object to reference the method; we can simply use the class name as a qualifier.

Singleton objects in Kotlin
The singleton object is one that only needs to be created once and can be used everywhere.

object SearchRepositoryProvider {
    fun provideSearchRepository(): SearchRepository {
        return SearchRepository()
    }
}

The above singleton object can be used as,

val repository = SearchRepositoryProvider.provideSearchRepository();


If you want to write a function or member of a class that can be called without having an instance of the class, you can do so using a companion object inside the class in Kotlin. 
So, by declaring the companion object, you can access the members of a class by name only. You can create a companion object by adding the Companion keyword in front of the object declaration.

  1. Create Repository

Create a simple repository that handles calling the GithubApiServie and builds the query string. Create a method in the repository that will allow you to build the string by taking location and language as parameters.

The search repository will look like this:

class SearchRepository(val apiService: GithubApiService) {
    fun searchUsers(location: String, language: String): Observable {
    return apiService.search(query =  "location:$location language:$language")
    }
}

In the preceding code snippet, we used the string template feature to create a query string. The string template starts with $ sign.

  1. Make a request and Observe API response using RxJava.

Now create the request and retrieve the API response using RxJava. In Kotlin code, it looks like this:

val repository = SearchRepositoryProvider.provideSearchRepository()
repository.searchUsers("Lagos", "Java")
        .observeOn(AndroidSchedulers.mainThread())
        .subscribeOn(Schedulers.io())
        .subscribe ({
            result ->
            Log.d("Result", "There are ${result.items.size} Java developers in Lagos")
        }, { error ->
            error.printStackTrace()
        })

Through this implementation, you can understand how to use Retrofit with Kotlin.

Role of DhiWise in Android app development

As of now you have a clear understanding of retrofit and its implementation. So it's time to move and improve your team productivity with DhiWise- An ultimate platform for developers to build enterprise-grade apps 2X faster with minimum resources.
The platform harnesses the power of automation to increase developers’ productivity while offering full flexibility of customization.

Yes, you hear it right!

With DhiWise Android Builder for Kotlin(Language recommended by Google for Android app development),  along with the supported libraries including Retrofit, developers can efficiently generate clean code for their app in a few steps.  
So what are you waiting for?  Try DhiWise Today!!

Reference:

https://www.segunfamisa.com/posts/using-retrofit-on-android-with-kotlin

https://www.journaldev.com/13639/retrofit-android-example-tutorial

https://www.youtube.com/watch?v=seuRVttjQdM

https://jakewharton.com/making-retrofit-work-for-you-ohio/