Loading...
Android

Great Android App Architecture [ Part 3 – Retrofit ]

Continuing from the last article, for fetching quotes for our app, we are going to use Retrofit and fetch quotes from this simple and free API Random Famous Quotes API.

Retrofit

API is straightforward and simple GET request

for getting single quotes from movie category will look something like this where count parameter is optional and by default will return 1 quote. You are going to need API key as well to be put in HTTP request header which you can get by signing up.

https://andruxnet-random-famous-quotes.p.mashape.com/?cat=movies&count=1

Typically you can obtain JSON response from REST API in java using URL and Connection classes as shown below,

Connection connection = Jsoup.connect(queryURL.toExternalForm())
        .header(headers_if_any)
        .timeout(0)
        .ignoreContentType(true);
Document document = connection.userAgent(Net.USER_AGENT).get();
response = new JsonParser().parse(document.text()).getAsJsonObject();

You can make this code work in this case for you, no problem. But the problem with this approach is too much boiler plate code to write. Plus overhead of converting incoming JSON to appropriate java objects, too much overhead. Imagine if you have to use 10 APIs in your code!

Retrofit comes to rescue! A type-safe REST client for Android and Java.

Retrofit will make your life easier. It will be little bit difficult to understand at first but believe me, once you get hands around it, you will be writing API codes within minutes! Don’t give up!

First things first, include dependency in your build.gradle file for your app. We are including gson library as well for converting incoming json to java object directly, without any code. And logging-interceptor for logging json response and requests for development purpose.


compile 'com.google.code.gson:gson:2.8.0'
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.3.1'

  • Android Network Permission:

    Retrofit is going to perform HTTP request and thus will require Internet permission to do so. You need to define the permission within the AndroidManifest.xml file. If you don’t, runtime exception will haunt you!

    <uses-permission android:name="android.permission.INTERNET">
    
  • API Endpoint:

    Before using API, you need to define API endpoint which you will be interacting with.  We will define interface and required methods for the same. We will define QuoteAPI interface and only one method getQuote for fetching one quote at time from server. Interface will look something like this.

    public interface QuoteAPI {
    
        @Headers({
                "X-Mashape-Key:your_api_key",
                "Content-Type: application/x-www-form-urlencoded",
                "Accept: application/json"
        })
        @GET("/")
        Call<Quote> getQuote(@Query("cat") String category,
                              @Query("count") int count);
    
    }
    

    You are seeing lot of annotations in above code. If you never came across annotations yet, they are very easy to understand and explained nicely here.

    @GET annotation used to mention request type and relative URL.
    @Header is used to mention any HTTP headers needed with the request.
    @Query parameters are added with the this annotation on a method parameter. They are automatically added at the end of the URL.

    We will get response in the form of JSON as below. Note that we already have defined Quote class which we can use to map this JSON data into.

    HTTP/1.1 200 OK
    Connection: keep-alive
    Content-Length: 117
    Content-Type: application/json
    Date: Sun, 25 Jun 2017 17:24:42 GMT
    Server: Mashape/5.0.6
    
    {
    "quote": "Oh, no, it wasn't the airplanes. It was Beauty killed the Beast.",
    "author": "King Kong",
    "category": "Movies"
    }
    
    
    public class Quote{
    
        private String quote;
        private String author;
        private String category;
    
    
        public String getQuote() {
            return quote;
        }
    
        public void setQuote(String quote) {
            this.quote = quote;
        }
    }
    
  • Retrofit in Action:
    After doing build up work, now it is time to reap the benefits of Retrofit! Code for doing so is also surprisingly just few lines.

    class QuoteRepository {
        private QuoteAPI quoteAPI;
    
        QuoteRepository(){
        }
    
        // ...
        LiveData<Quote> getQuote(String category, int count) {
            //live data with setValue method exposed
            final MutableLiveData<Quote> data = new MutableLiveData&amp<>();
    
            //For logging JSON responses in logcat
            HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
            interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
            OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
    
            //building retrofit object 
            //with default GSON convertor for converting incoming data
            //to Quote objects
            Retrofit.Builder builder = new Retrofit.Builder()
                    .baseUrl("https://andruxnet-random-famous-quotes.p.mashape.com/")
                    .client(client)
                    .addConverterFactory(GsonConverterFactory.create());
    
            Retrofit retrofit = builder.build();
            quoteAPI = retrofit.create(QuoteAPI.class);
    
            //asynchronous API call with callbacks
            quoteAPI.getQuote(category, 1).enqueue(new Callback&amp<Quote>() {
                @Override
                public void onResponse(Call<Quote> call, final Response&amp<Quote> response) {
                    data.setValue(response.body());
                }
    
                @Override
                public void onFailure(Call<Quote> call, Throwable t) {
                    Log.v(Constants.TAG, t.getMessage());
                }
             });
    

    But wait, you would ask, where is the code which will actually fetch quote from the server? Well, retrofit took care of it for us and we don’t need to know how it did it. Code is generated while builds using annotations and all we wanted to do was to call a method written in API endpoint (getQuote).

    If everything goes well, you will get Quote object and JSON request and response will be logged in Logcat for you to monitor. Initially, Retrofit might look complex to you, but it will pay off in future once you get hands on it! You can check out this link for detailed retrofit uses, this guy has done awesome job describing it!

    You can try this code now in Studio to see how your app is working out! As of now, it will show blank page on launch and in background API call will happen. After fetching data, UI will be updated and you can see the quote on screen. But wait, this guy promised us something different and not delivering, let’s kill him. Wait, I will demonstrate offline caching and pull down to refresh in next article. Keep reading!

 

I will be writing more articles about tips and tricks for making most of your android application in future, subscribe our newsletter for getting the articles directly in your inbox. Subscription box can be found on top right side of this article of you are on PC and at the bottom of this article if you are on mobile device.

 

Sharing is caring!

8 comments
Leave a Reply

Your email address will not be published. Required fields are marked *