Simple way to Consuming APIs with Retrofit

There are some basic things we do during in our applications development journey. One that is always related with making HTTP requests and getting the responses. This is a really pain in the ass. Thankfully, There is a library for this kind of situations.

What is Retrofit?

Retrofit is type-safe HTTP client for Android and Java by Square, Inc.

How to use it?

We need libraries in our dependencies to use Retrofit in our Android projects. We also need a converter used for JSON format : GSON.

compile 'com.squareup.retrofit:retrofit:2.0.0-beta1'
compile 'com.squareup.okhttp:okhttp:2.2.0'
compile 'com.google.code.gson:gson:2.3'

How to construct Android Client?

I want to show you all necessary fundamentals for a well-structured Android client. To achieve this, We need at least one interface to write our query lists, model classes to retrieve the api responses, a restclient to make our calls.

Step 1 : Creating Pojos

Retrofit comes with Google’s GSON by default. There is one thing we should do here in the first step. We need to define model classes for our response object. Response will be mapped magically.

public class Contributor {
public String login; // GitHub username.
public int contributions; // Commit count.
}

Sometimes, you can have different names if you use @SerializedName annotation to specify the name of the field in the JSON.

public class DeviceResponse extends BaseResponse {

@SerializedName("device_id")
public Integer deviceId;

@SerializedName("all_full")
public boolean isCompleted;
}

I need to warn you about one important thing here. if you want to develop well-defined OOP based standart application, you should define a base response model class for common attributes in the returning JSON.

public class BaseResponse {

@SerializedName("msg")
public String msg;

@SerializedName("status")
public int status;
}

Step 2: Creating RestInterface Class

Create an interface called RestInterface here to manage all url calls. In this interface, specify the type of the request like POST, GET, PUT, etc..

public interface RestInterface {

@GET("/video/list")
void getPlaces(@Query("key") String key, Callback<List<VideosWrapper>> places);

@GET("/faq/list")
FaqResponse getFaq(@Query("key") String key, @Query("code") String code);

@POST("/device/save")
DeviceResponse saveDevice(@Body Device device, @Query("key") String key);

@FormUrlEncoded
@POST("/user/remind")
BaseResponse remindPassword(@Field("email") String email,
@Query("key") String key);

}

for more information about specifying different types of request in your application, you should visit offical page of Retrofit.

http://square.github.io/retrofit/

Step 3: Creating RestClient

to create a restclient, I strongly recommend you to create a base class called BaseService. In this base service, we can define OkHttpClient common features, StethoUtil, Api end point etc.

After creating a base service class you can define main rest service classes here. I strongly advise you to group this classes into subclasses according to Api structure. For instance, A rest service class can be about user stuffs like login, register etc. In this situation, you should define a class that called UserService.

public final class UserService {

private static final RestInterface api = BaseService.getApi();

private UserService() {

}

public static BaseResponse remindPassword(String email) {
BaseResponse response = new BaseResponse();
try {
response = api.remindPassword(email, BuildConfig.REST_KEY);
} catch (RetrofitError error) {
if (error.getKind() == RetrofitError.Kind.NETWORK
|| error.getKind() == RetrofitError.Kind.UNEXPECTED) {
response.msg = error.getMessage();
} else {
response.msg = error.getMessage();
}
Timber.e(error.getMessage());
} catch (Exception e) {
response.msg = e.getMessage();
Timber.e(e.getMessage());
}
return response;
}
}

This is a screenshot of a package architecture that you can use in your project. I strongly recommend you to use this one.

Otto Meets Retrofit

Since Retrofit supports asynchronous requests, asynchronous requests don’t have a return type. Instead, you should define method that requires a typed callback as last method parameter.

public void getAllSongList() {

restService.getAllSongList(new Callback<SongWrapper>() {

@Override
public void success(SongWrapper songWrapper, Response response{
BusProvider.getInstance().post(new OnAllSongListFetchedEvent(songWrapper.getSongs()));
}

@Override
public void failure(RetrofitError error) {
Log.v(TAG, error.getMessage());
}
});
}

You should subscribe to the bus and start watching for events that request an API call. When it catches the event, creates a callback which will fire off a new event when the response is finished in succesfully.

Conclusion

Once you start using Retrofit, you have a smoother relationship with HTTP based APIs on Android. Be smart, use Retrofit.

Resources:

https://futurestud.io/blog/retrofit-getting-started-and-android-client/

http://blog.robinchutaux.com/blog/a-smart-way-to-use-retrofit/

https://corner.squareup.com/2013/05/retrofit-one-dot-oh.html