Retrofit to make API calls in SUSI.AI Android Client

In the SUSI.AI app, I found the extensive use of “Retrofit” to make API calls to the server. While working on a part of the app, I faced some difficulty regarding the implementation of “Retrofit”.  Though I learned and overcame the problems, I realized that others would face a similar problem. So, today I am writing this blog explaining how to implement “Retrofit” using the help of “SUSI.AI” android client.

Working of API Calls:

Android networking or any networking works in the following way:

  • Request— An HTTP request is made to a certain URL, with all the supplied parameters.
  • Response — The request created returns a response, usually in the JSON format.
  • Parse & Store —The JSON returned is parsed and is being used accordingly.

In Android, we use —

  • Okhttp — For creating an HTTP request with all the proper headers
  • Retrofit — For making the request
  • Moshi / GSON — For parsing the JSON data
  • Kotlin Coroutines — For making non-blocking (main thread) network requests.
  • Picasso / Glide— For downloading an image from the internet and setting it into an ImageView.

Obviously, these are just some of the popular libraries but there are others too.

How to use Retrofit?

First of all we need to import certain libraries in the app level gradle file.

Don’t forget to add the following in the manifest file.

Now, create an interface. The API link mentioned in the interface would be used to fetch data from the server.

Now create a class to parse the JSON data.  Here, we have used a Gson Converter and so the JSON response is automatically converted to the respective.

Here Session and Settings are also a data class. These data classes are framed according to the response that we receive.

Now, create a Retrofit Builder with Base URL and GsonConverterFactory. This builder will be useful to make the API calls.

Create a service for Retrofit with your service interface. Then, create a queue which will be used to de-serialize the JSON. 

Resources: 

Documentation: Retrofit

Blog: Retrofit

Tutorial: Retrofit Video Tutorial

SUSI.AI Android App: PlayStore GitHub

Tags:

SUSI.AI Android App, Kotlin, SUSI.AI, FOSSASIA, GSoC, Android, Retrofit, API calls

Continue Reading

Use objects to pass multiple query parameters when making a request using Retrofit

There are multiple instances where there is a need to make an API call to the SUSI.AI server to send or fetch data. The Android client uses Retrofit to make this process easier and more convenient.
While making a GET or POST request, there are often multiple query parameters that need to sent along with the base url. Here is an example how this is done:

@GET("/cms/getSkillFeedback.json")
Call<GetSkillFeedbackResponse> fetchFeedback(
                          @Query("model") String model,
                          @Query("group") String group,
                          @Query("language") String language,
                          @Query("skill") String skill);

 

It can be seen that the list of params can be very long indeed. A long list of params would lead to more risks of incorrect key value pairs and typos.

This blog would talk about replacing such multiple params with objects. The entire process would be explained with the help of an example of the API call being made to the getSkillFeedback.json API.

Step – 1 : Replace multiple params with a query map.

@GET("/cms/getSkillFeedback.json")
Call<GetSkillFeedbackResponse> fetchFeedback(@QueryMap Map<String, String> query);

 

Step – 2 : Make a data class to hold query param values.

data class FetchFeedbackQuery(
       val model: String,
       val group: String,
       val language: String,
       val skill: String
)

 

Step – 3 : Instead of passing all different strings for different query params, pass an object of the data class. Hence, add the following code to the ISkillDetailsModel.kt interface.

...

fun fetchFeedback(query: FetchFeedbackQuery, listener: OnFetchFeedbackFinishedListener)
...

 

Step – 4 : Add a function in the singleton file (ClientBuilder.java) to get SUSI client. This method should return a call.

...

public static Call<GetSkillFeedbackResponse> fetchFeedbackCall(FetchFeedbackQuery queryObject){
   Map<String, String> queryMap = new HashMap<String, String>();
   queryMap.put("model", queryObject.getModel());
   queryMap.put("group", queryObject.getGroup());
   queryMap.put("language", queryObject.getLanguage());
   queryMap.put("skill", queryObject.getSkill());
   //Similarly add other params that might be needed
   return susiService.fetchFeedback(queryMap);
}
...

 

Step – 5 : Send a request to the getSkillFeedback.json API by passing an object of FetchFeedbackQuery data class to the fetchFeedbackCall method of the ClientBuilder.java file which in turn would return a call to the aforementioned API.

...

override fun fetchFeedback(query: FetchFeedbackQuery, listener:  
                                   ISkillDetailsModel.OnFetchFeedbackFinishedListener) {

   fetchFeedbackResponseCall = ClientBuilder.fetchFeedbackCall(query)
   ...
}

 

No other major changes are needed except that instead of passing individual strings for each query param as params to different methods and creating maps at different places like in a view, create an object of FetchFeedbackQuery class and use it to pass data throughout the project. This ensures type safety. Also, data classes reduce the code length significantly and hence are more convenient to use in practice.

Resources

Continue Reading
Close Menu
%d bloggers like this: