Improved Retrofit Call

2 min read Original article ↗

I just didn't like the way Retrofit is calling methods and I wanted to improve it. I believe error handling can be done much nicer. Here is what I did.

Preparing web service object to call remote methods:

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("http://example.com/web-api/v1/")
        .addConverterFactory(GsonConverterFactory.create())
        .build();

WebService webService = retrofit.create(WebService.class);

Normal Retrofit web service call is like this:

webService.listShops().enqueue(new Callback<List<Shop>>() {
    @Override
    public void onResponse(Call<List<Shop>> call, Response<List<Shop>> response) {
        // response status handling and getting list of shops
    }

    @Override
    public void onFailure(Call<List<Shop>> call, Throwable t) {
        // error handling
    }
});

As you can see, we should handle response status and errors for every single call to web service. But with this class, you can have a single error handler for failures and other bad requests:

WebServiceCall webServiceCaller = new WebServiceCall(throwable -> {
    Log.e(TAG, throwable.getMessage());
});

webServiceCaller
        .call(webService.listShops())
        .then((List<Shop> response) -> {
            // do whatever you want with the list of shops. no response, just your object
        });

Or you can have no error handling at all!

WebServiceCall webServiceCaller = new WebServiceCall();

webServiceCaller
        .call(webService.listShops())
        .then((List<Shop> response) -> {
            // do whatever you want with the list of shops. no response, just your object
        });

Or you can handle errors of a specific call and let others be handled by the global error handler:

WebServiceCall webServiceCaller = new WebServiceCall(this);


webServiceCaller
        .call(webService.listPeople())
        .then((List<Person> response) -> {
            // do whatever you want with the list of people
        });

webServiceCaller
        .call(webService.listShops())
        .catches(throwable -> {
            // THIS SHOULD BE CALLED BEFORE "then" METHOD
            Log.e(TAG, throwable.getMessage());
        })
        .then((List<Shop> response) -> {
            // do whatever you want with the list of shops. no response, just your object
        });

webServiceCaller
        .call(webService.getShop(123))
        .then((Shop response) -> {
            // do whatever you want with the shop
        });