Safe Retrofit calls extension with kotlin Coroutines for Android in 2021 — Part I

Christopher Elias
Nerd For Tech
Published in
4 min readMay 15, 2021

--

Photo by Fotis Fotopoulos on Unsplash

Hello 👋, today Im going to teach you how to execute network calls with retrofit in a safe and kotlin idiomatic way. At the end of this small series you could end up with something like this:

Here you have a Clean Architecture structure from the data layer to the domain layer and the presentation layer.

The gist from above is showing you how is executed the retrofit call and handle the result failure or success in your ViewModel / Presenter/ etc.
If you don’t understand the content of the gist, don’t worry I will go step by step in a very resumed but concrete explanation.

If you want to go straight to the code, checkout this playground project I made about movies.

What’s the problem?

First thing first, why do you need coroutines for execute a network call (with retrofit or any other HTTP client)? Well my friend, as you already know (or probably not) when you start your android apps it creates a new Linux process with a single thread (main thread or UI thread if you want). This thread is in charge of drawing your view components, widgets, etc. Everything related to the UI. It is completely forbidden to do other things on this thread because the app can crash. Check out the official docs for more detailed information.

Now we know that we are not allowed to perform heavy tasks like network calls, database operations, read/write files on the UI thread cause it will get laggy and we could get an ANR exception and our apps will crash.

Are there any solutions?

In the old android coding times people used to create their own Thread Pools and manage the creation and maintenance of the threads by themselves 🤯! Believe me kiddo, that is not something you wanna go into. Other solutions imply AsyncTasks which wasn’t so flexible and is deprecated now. Those where real though years. My respect for all those developers who are developing android apps since there.

Then, as the platform where evolving also the challenges, and the way to overcome those challenges require new and more flexible approaches. That’s when RxJava was the new savior for Android Apps. RxJava is a good solution for asynchronous tasks, but it comes with it’s own pitfalls:

  • A long learning curve. It wasn’t easy to understand at the first time, because you have to change your mindset to a reactive programming one with a lot of operators and marbel diagrams 😵.
  • It adds like 2MB+ to your final APK size
  • It was like killing a bug with a bazooka. You probably wouldn't use the 50% of utilities from that library, and only use it for one problem, asynchronous task.

Coroutines to the rescue

In 2017 Google made official the use of Kotlin for Android Development and since there things where evolving really fast. They come out with a incorporated solution for asynchronous tasks in the 1.1 version of the language, the famous Coroutines. This was an out of the box solution for those who where coding in Kotlin!

A coroutine is an instance of suspendable computation. It is conceptually similar to a thread, in the sense that it takes a block of code to run that works concurrently with the rest of the code. However, a coroutine is not bound to any particular thread. It may suspend its execution in one thread and resume in another one.

Coroutines can be thought of as light-weight threads, but there is a number of important differences that make their real-life usage very different from threads.

Kotlin docs

Let’s wrap it all together

In order to execute a network call safely we need to do the following things:

  • Ensure that it is not being executed in the main thread — Coroutine Dispatchers is going to be our tool here.
  • We probably gonna need to parse some backend error response too — We are going to use Moshi for parsing JSON.
  • If we want, we could add some kind of a middleware functionality in order to execute our network call only if all those middlewares are conditions are supplied. — This is optional.

We got our requirements for our network call extension wrapper, bu there is one question floating in the air… how are the exceptions handled with coroutines 🤔?

Exceptions are handled very straight forward with a try catch block. Look at this blog from Manuel Vivo talking about it. In fact, we are also going to handle our exceptions with a try catch block under the hood 🤫 but, we are not going to pass the exception through the layers of our app.

Instead of that, we are going to pass custom Failures wrapped in our awsome “Either” class (you can find similar implementations even in google samples, like this Result sealed class).

The Either class is just a sealed class that can be a Error or a Success object at a given time. It also contain some extra methods I implement for perform some kind of map operations based on the Arrow functional programming library. The Either class is nothing new, I discovered when I was reading this amazing article from Fernando Cejas.

If you don’t know what sealed classes are, check out this video from Florina Muntenescu

We have our basis set up, time to code. Check out part 2 👉 here.

--

--