Android Retrofit for beginners

Abhishek Pathak
5 min readOct 20, 2022

--

Retrofit is a type-safe HTTP networking library used for Android build by Square and maintained by Google. It is the most used and most efficient library for network requests in applications. It is Annotation based library. Retrofit was even better since it was super fast, offered better functionality, and even simpler syntax. Most developers since then have switched to using Retrofit to make API requests.

Advantages of using retrofit

  • It is very fast and easy to use as it is annotation based library.
  • It supports request cancellation.
  • It supports post requests and multipart uploads.
  • It enables direct communication with the web service.
  • Supports dynamic URLs.
  • Supports convertors.
  • It supports both synchronous and asynchronous network requests.
  • It caches responses to avoid sending duplicate requests.

Disadvantages of retrofit (Features must be required to make retrofit more better)

  • It does not support setting priorities.
  • Retrofit is not having retry policy concept inbuild as Volley have.
  • Retrofit is not having request prioritization inbuild.
  • It does not support image loading. It requires other libraries such as Picasso and Glide.

Annotations in retrofit

Retrofit provides an annotation for each of the main standard request methods. You simply use the appropriate Retrofit annotations for each HTTP method

@GET : It will allow to fetch available data request.

@POST: It will allow to post a data to server as request.

@PUT: It will allow to update a existing data to server as a whole request as body object.

@PATCH: It will allow to make an API request to update a particular field in exsiting data on server database.

@DELETE: It will allow to make a delete API request.

I had taken an basic service class to demonstrate how to use these annotations.

/*
This class all kinds of Retrofit requests
@GET,
@POST,
@PUT,
@PATCH,
@DELETE
*/
interface ApiService {

/*
In this API call we are fetching a post on the basis of post id
*/
@GET("posts/{postId}")
fun getPosts(
@Path("postId") postId: String,
): Call<PostsResponse>

/*
In this API call we are fetching all the posts available
*/
@GET(END_POINT)
fun getAllPosts(): Call<PostAllData>

/*
In this API call we are adding a new post by using field
*/
@FormUrlEncoded
@POST(END_POINT)
fun postPosts(
@Field("title") title: String,
@Field("body") body: String,
@Field("userId") userId: String
): Call<PostsResponse>

/*
In this API call we are adding a new post by using body
*/
@POST(END_POINT)
fun postPosts(@Body postRequest: PostRequest): Call<PostsResponse>

/*
In this API call we are update the post details
*/
@FormUrlEncoded
@PUT("posts/{postId}")
fun updatePosts(
@Path("postId") postId: String,
@Field("id") id: String,
@Field("title") title: String,
@Field("body") body: String,
@Field("userId") userId: String
): Call<PostsResponse>


@FormUrlEncoded
@PATCH("posts/{postId}")
fun updatePostTitle(
@Path("postId") id: String, @Field("title") title: String
): Call<PostsResponse>

/*
In this API call we are deleting a post on the basis of post Id
received as parameter
*/
@DELETE("posts/{id}")
fun deletePost(@Path("id") id: String): Call<Unit>

/**
* Makes a POST request to the specified endpoint with the provided request body.
*
* @param requestBody The data to be sent in the request body.
* @return A Retrofit [Call] representing the asynchronous response.
*/
@POST("your_endpoint")
fun postData(@Body requestBody: YourRequestBodyClass): Call<YourResponseClass>


}

How to make Retrofit builder?

object RetrofitBuilder {

private lateinit var retrofit: Retrofit

fun getRetrofit(): Retrofit {
if (!this::retrofit.isInitialized) {

val loggingInterceptor = HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
}

val client = OkHttpClient.Builder()
.addInterceptor(loggingInterceptor)
.build()

retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build()
}

return retrofit
}
}

How to call them these API interface methods?

I am sharing a part of the code how I am requesting these API service methods.

private fun getAPost() {
apiService.getPosts("1")
.enqueue(object : Callback<PostsResponse> {
override fun onResponse(
call: Call<PostsResponse>,
response: Response<PostsResponse>
) {
Log.i("tag", response.message())
}

override fun onFailure(call: Call<PostsResponse>, t: Throwable) {
// binding.loader.visibility = View.GONE
Log.i("tag", t.message.toString())
}
})
}


private fun getALlPosts() {
apiService.getAllPosts()
.enqueue(object : Callback<PostAllData> {
override fun onResponse(
call: Call<PostAllData>,
response: Response<PostAllData>
) {
Log.i("tag", response.message())
}

override fun onFailure(call: Call<PostAllData>, t: Throwable) {
// binding.loader.visibility = View.GONE
Log.i("tag", t.message.toString())
}
})
}


private fun deletePost() {
apiService.deletePost("1")
.enqueue(object : Callback<Unit> {
override fun onResponse(
call: Call<Unit>,
response: Response<Unit>
) {
Log.i("tag", response.message())
}

override fun onFailure(call: Call<Unit>, t: Throwable) {
// binding.loader.visibility = View.GONE
Log.i("tag", t.message.toString())
}
})
}

private fun updatePostTitle() {
apiService.updatePostTitle("1", "London")
.enqueue(object : Callback<PostsResponse> {
override fun onResponse(
call: Call<PostsResponse>,
response: Response<PostsResponse>
) {
Log.i("tag", response.body()?.title!!)
}

override fun onFailure(call: Call<PostsResponse>, t: Throwable) {
// binding.loader.visibility = View.GONE
Log.i("tag", t.message.toString())
}
})
}


private fun updatePosts() {
apiService.updatePosts("1", "1", "London", "good city", "1")
.enqueue(object : Callback<PostsResponse> {
override fun onResponse(
call: Call<PostsResponse>,
response: Response<PostsResponse>
) {
Log.i("tag", response.body()?.title!!)
}

override fun onFailure(call: Call<PostsResponse>, t: Throwable) {
// binding.loader.visibility = View.GONE
Log.i("tag", t.message.toString())
}
})
}

private fun postComment() {
apiService.postPosts("London", "good city", "1")
.enqueue(object : Callback<PostsResponse> {
override fun onResponse(
call: Call<PostsResponse>,
response: Response<PostsResponse>
) {
Log.i("tag", response.body()?.title!!)
}

override fun onFailure(call: Call<PostsResponse>, t: Throwable) {
// binding.loader.visibility = View.GONE
Log.i("tag", t.message.toString())
}
})
}

private fun postPosts() {
apiService.postPosts(PostRequest("London", "good city", "1"))
.enqueue(object : Callback<PostsResponse> {
override fun onResponse(
call: Call<PostsResponse>,
response: Response<PostsResponse>
) {
Log.i("tag", response.body()?.title!!)
}

override fun onFailure(call: Call<PostsResponse>, t: Throwable) {
// binding.loader.visibility = View.GONE
Log.i("tag", t.message.toString())
}
})
}

Retrofit Converters

Retrofit can be configured to use a specific converter. This converter handles the data de-serialization.

  • Gson: com.squareup.retrofit:converter-gson
  • Jackson: com.squareup.retrofit:converter-jackson
  • Moshi: com.squareup.retrofit:converter-moshi

Let’s do basic implementation of Retrofit

We will be fetching from JSONPlaceholder open source API by connecting to a service, which will provide Comments data in JSON form and display it on UI.

So let’s begin…

Step 1 : Add the following dependencies to your app level gradle

Step 2 : Add internet permission to Android Manifest.xml

Step 3: add request and response data classes like Comment.kt, PostRequest, PostsResponse etc.

Step 4: Add API client for retrofit builder

Step 5: Add API Service interface.

interface WeatherApiService {
@GET("data/2.5/weather")
suspend fun getCurrentWeather(
@Query("lat") lat: Double,
@Query("lon") lon: Double,
@Query("appid") apiKey: String
): Response<WeatherResponse>
}

Step 6: Consume API and show the result.

I am adding my implementation for check out the full repository, you can clone or fork from the below link. Happy coding :)

Upnext Topic: Retrofit Interceptor

Thanks for reading this article. Be sure to click 👏 below to applause this article if you found it helpful. It means a lot to me.

--

--