When Obvious was brought in to refactor a big legacy app last year, we found ourselves in a strange situation. Our client was maintaining a common library for handling networking — HTTP, FCM, MQTT — across all apps under their brand. This library (let’s call it SadLibrary) had an API that was badly designed and dated, but not using it was not an option.
Most modern Android apps use Retrofit to access REST-style APIs in an elegant and simple way. We wanted to see if we could make Retrofit work with SadLibrary and decided to give it a shot. Our initial idea was to fork Retrofit as RetroUnfit and plug in SadLibrary instead of OkHttp. Thankfully, this spectacularly bad idea was shot down in no time. After going through Retrofit’s code, learning how Retrofit delegates calls to OkHttp and, how OkHttp further delegates them to interceptors, we realised that the correct solution was far simpler.
OkHttp and The Magical Interceptors
For those unaware, OkHttp uses interceptors for not only letting clients hook into calls and modify their request/response bodies, but also for finally running the call on the network. This is done inside the very last interceptor and can be seen in action here: okhttp3.RealCall#194.
So to make Retrofit work with SadLibrary, all we needed to do was add an interceptor that redirects all network requests from OkHttp and forwards them to SadLibrary. Here’s an example:
That’s all! Retrofit could now be used for making network calls without dealing with SadLibrary and its sad API!
Making Retrofit work for you
Using Retrofit in this manner is very similar to what Nick Butcher does in his beautiful Dribbble client, Plaid. Since Dribbble does not provide a search API, Plaid manually downloads the search page as HTML and parses it using Jsoup. But, instead of leaking this ugliness to the rest of the app, this functionality is exposed through Retrofit as if it were an actual Dribbble API.
You can watch Jake Wharton explain this in more detail in his talk, Making Retrofit Work For You (GDG Cincinnati).
Cover photo by Bryan Colosky.