OkHttp Interceptors in Android

May 25 2021 · Kotlin 1.4, Android 5, Android Studio 4.1

Part 1: Implementing OkHttp Interceptors

03. Setup HttpLoggingInterceptor & Debug API Calls

Episode complete

Play next episode

Next
About this episode
Leave a rating/review
See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 02. Set Up the Project Next episode: 04. Implement a Custom Logger & Redact Headers

Get immediate access to this and 4,000+ other videos and books.

Take your career further with a Kodeco Personal Plan. With unlimited access to over 40+ books and 4,000+ professional videos in a single subscription, it's simply the best investment you can make in your development career.

Learn more Already a subscriber? Sign in.

Transcript: 03. Setup HttpLoggingInterceptor & Debug API Calls

HttpLoggingInterceptor is an Interceptor that lets you log all the API requests made by your app as well as the responses returned by the server.

To add HttpLoggingInterceptor to your project, first open the app module build.gradle. In the dependencies block, add the following line of code:

implementation “com.squareup.okhttp3:logging-interceptor:4.9.0”`

This line adds the dependency for HttpLoggingInterceptor which is shipped as a separate library compared to OkHttp. Click ‘Sync Now’ and wait for the dependency to sync.

Next, you head over to the file named OkHttpProvider.kt inside the network package. Here, there is a function named getOkHttpClient:

fun getOkHttpClient(): OkHttpClient {
    return if (okHttpClient == null) {
        val okHttpClient = OkHttpClient.Builder()
            .readTimeout(REQUEST_TIMEOUT, TimeUnit.SECONDS)
            .connectTimeout(REQUEST_TIMEOUT, TimeUnit.SECONDS)
            .build()
        OkHttpProvider.okHttpClient = okHttpClient
        okHttpClient
    } else {
        okHttpClient!!
    }
}

This function creates an instance of OkHttpClient, configures it with read and connection timeouts, and finally returns the instance.

Before creating the OkHttpClient instance, create an instance of HttpLoggingInterceptor by adding the following line of code:

val loggingInterceptor = HttpLoggingInterceptor()

You then have to specify the extent of logging required.

You can choose among four different levels: 1. NONE 2. BASIC 3. HEADERS 4. BODY. NONE is the default logging level.

The BASIC logging level logs only bare minimum information such as the request URL, request type, response code, etc.

The HEADERS logging level logs all the information covered by the BASIC level and also the headers of the request and the response.

The BODY logging level logs all the information covered by the HEADERS level and also the body of the request and the response. Let’s see some of the logging levels in action!

Back in the getOkHttpClient() function, set the logging level to BASIC by adding the following line of code:

loggingInterceptor.level = HttpLoggingInterceptor.Level.BASIC

In this line, you set the logging level to BASIC by assigning the enum value HttpLoggingInterceptor.Level.BASIC to the level attribute of the HttpLoggingInterceptor instance.

Once the HttpLoggingInterceptor instance is configured, add it to the OkHttpClient instance as follows:

val okHttpClient = OkHttpClient.Builder()
    .readTimeout(REQUEST_TIMEOUT, TimeUnit.SECONDS)
    .connectTimeout(REQUEST_TIMEOUT, TimeUnit.SECONDS)
    .addInterceptor(loggingInterceptor)
    .build()

Build and run the app. Once the app is running, open the Logcat tab inside Android Studio. You will see logs of the API request as well as the response.

Close the Logcat tab and switch over to the emulator. Click on any of the movies. You will notice that the app shows an error state. Luckily, you are already logging the responses to all your API calls.

Open the Logcat tab and check the response logs. You will notice that the response has a status code of 401 which indicates an Unauthenticated Request. But this data is insufficient to correctly debug the issue.

Close the Logcat tab and go back to OkHttpProvider. Change the logging level to BODY as follows:

loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY

This will log the headers as well as the body of all the responses. If you instead used HEADERS, it would log just the headers. Build and run the app.

Click on any of the movies again. Switching to the Logcat tab, you can now see more details about the response. The response body states that an invalid API key was sent in the request. You have found the cause of the error.

Close the Logcat tab and open the file named MovieApi in the network package. You will notice that you are sending an API key as a query parameter for the getPopularMovies method and not the getMovieDetailsmethod.

Fix this by adding the parameter for the getMovieDetails method too:

@GET("/3/movie/{id}")
fun getMovieDetails(@Path("id") id: Long, @Query("api_key") api_key: String = BuildConfig.THE_MOVIE_DB_API_TOKEN): Call<MovieDetailsModel>

If now you click on any of the movies, you will see that the details page works correctly now. You have successfully integrated HttpLoggingInterceptor in your app and used it to debug an issue with your API calls.