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

Christopher Elias
May 17 · 4 min read
Photo by Fotis Fotopoulos on Unsplash

So this is it. The end of this small series. If you haven’t seen the first two parts, here are the links to it.

Quick Recap!

First of all, congrats for having progressed this far 👏.

  • We needed an extension for make retrofit calls safety ✔️.
  • We needed a way to parse the exceptions and return them into human readable objects✔️.
  • We needed to return a a success or a failure as result✔️.

And now we are going to add our middleware. This functionality will allow us to prevent the execution of the retrofit calls if any of its conditions is not supplied. Something like

if(middlewareConditionsAreSupplied) executeRetrofitCall else NOT!

Middleware Requirements

  • Extendable — Our app can have more than one Middleware. We could have a middleware that validates the network connection, another that validates some specific feature params, etc. Anything you can image in order to prevent the execution of the retrofit call.
  • Easy to inject — We need to create an object that can be easy to inject in our safe retrofit call wrapper extension.
  • Easy to mock — We need somehow to make this middleware easy to mock in order to prevent our unit tests become hard to test.
  • Retrieve all — We need a way to retrieve all our middlewares and validate each one of them.

Code time 🔥

Now that we set up the requirements for the Middleware, we can code. Let’s start with the first part. We are planning to integrate this functionality to our call wrapper extension, therefore, it means that the failure of a middleware is going to return a Failure object. That it’s our start point.

class NetworkMiddlewareFailure(
val middleWareExceptionMessage: String,
) : Failure.CustomFailure()

Easy cake. Let’s move to the next steep. Our app can have multiple middleware objects, and any of them needs to be validated somehow, let’s use the inheritance principle in order to accomplish this step.

This class will do the job. Every middleware we want to create will going to extend this class and override the isValid() method (here is the place to put our our logic) and the failure variable which extend from our custom failure from above.

Let’s create a simple middleware then!

Middleware that validates if the phone is connected to the internet.

The class from above is responsible for tell us if we are connected to the internet or not with the help of the connectivityUtils interface (the implementation class is somewhere hided).

If the isValid() method return false, then we are going to use the NetworkMiddlewareFailure with a custom message from our res/strings folder with the help of the resourceProvider interface. As you can see, our implementation is very flexible and allow us to use whatever we want to create a middleware.

Ok, we can create a lot of middlewares, and now what…? We need some way to provide all our middlewares and run the isValid() method on each of them 🤯!

Hey hey hey 👊💥! Don’t panic. We can solve this problem very easily with the dependency inversion principle. It is better for us to depend on abstractions rather than implementations. Let’s create an interface that would do what we want.

Interface with one method to retrieve all the BaseNetworkMiddleware instances.

Now is the turn for the implementation. We are going to create a class that implements our MiddlewareProvider interface and overrides that getAll() method in order to return all of our middleware objects. We can get a little bit fancy here and do it with a builder pattern.

MiddlewareProvider that store all the middleware instances in a private list.

As you can see, the class above is going to add all the middlewares you want. You only need to provide this class in your dependency injection graph which can be from dagger or koin or whatever.

Sample on how to provide your MiddlewareProvider to your DI graph.

Now we have a singleton instance of our middleware provider. Let’s modify the call wrapper extension!

Well done my friend 👏! You have implemented a middleware to our extension and make it even safer! Now you can use it as I show you in the first part of these series.

I hope you like it. If you have any suggestions, improvements, complaints, jokes, etc. Add a comment, file and issue, generate a PR, etc! Stay safe!

See how this implementation is used on this project

See you later! 👋

Nerd For Tech

From Confusion to Clarification

Nerd For Tech

NFT is an Educational Media House. Our mission is to bring the invaluable knowledge and experiences of experts from all over the world to the novice. To know more about us, visit https://www.nerdfortech.org/. Don’t forget to check out Ask-NFT, a mentorship ecosystem we’ve started

Christopher Elias

Written by

Android Software Engineer | Android Blogger | 1st Place at Apps Up 2020 | Surf passionate

Nerd For Tech

NFT is an Educational Media House. Our mission is to bring the invaluable knowledge and experiences of experts from all over the world to the novice. To know more about us, visit https://www.nerdfortech.org/. Don’t forget to check out Ask-NFT, a mentorship ecosystem we’ve started

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store