Android and Rest



My PostManLib android library had a quite troubled genesis. Some infos can be found in this old post , but bear in mind that I only kept the skeleton of what I wrote at that time (which, by the way, was inspired by this talk).

The api was (to be kind) a bit clunky, and I recently chose to rewrite / finish it. Apart from its clunkyness, one thing was missing:

OAuth Authentication

OAuth authentication is quite common for android apps, since it is a widely supported authentication system. Looking for "inspiration" I came across https://github.com/fernandezpablo85/scribe-java which not only provides oauth out of the box, but already provides a good and well tested abstraction for http rest interactions. I then chose not to reinvent the wheel and to delegate oauth and http interaction entirely to scribe.

Why asynchronous rest calls in android are important:


In android, performing time consuming work in the ui thread may result in ANR errors, and obviously rest calls belong to this category. What postmanlib does is to decouple the requests and execute them inside intent services, providing a way to get notified of calls results.

What postmanlib offers:


  • OAuth login using a webview hosted inside a fragment dialog. Every interaction is performed asynchronously. Just call registerOAuthService and the registration will happen
  • Asynchronous rest calls (oauth-ed or not) performed inside an intent service
  • Multiple api handling - token storage

Given that the interaction is performed inside an intent service, all the well known problems related to asynctasks are avoided. 

What postmanlib does not offer:


  • Storage: the data received in background can be stored in the user's favorite storage. I strongly suggest to use a content provider, using my automatic content provider generator
  • Parsing: the plain text received must be interpreted. There is plenty of json / xml parsing library, just pick one



Library Architecture





A singleton object collects the requests to perform the rest calls in background. 
The requests are parcelable objects that are passed inside an intent to the intent services. Using the command pattern along with the strategy pattern to implement the interaction resulted in a much cleaner api (more details about the structure can be found in the git repository).


All the client application has to do is to perform oauth requests is to create and register a oauthservice builder. 
I had to wrap the original scribe oauth service builder because I had to store all the tokens in order to restore them whenever the singleton is garbage collected.

After performing the registration (which is done using a OAuthHelper class), a registered api can be used to sign any request sent. The only difference between oauth-ed and plain requests is that in the first case we specify a signer.



TL;DR


I really like the way the library grew up (not just because I wrote it :-) ). Scribe performs an excellent job in abstracting oauth registration and http interaction, so I could focus on asynchronous interaction with it.
The registration process is more than trivial, and rest requests are strongly decoupled from the activities.
As told earlier, it can be found here: https://github.com/fedepaol/PostmanLib--Rings-Twice--Android

I think this library might be of some help to anybody who wants to interact with webservices and want to go beyond the too often badly used async tasks.
A real world sample (with no oauth, sorry) can be found in my AndAppennino application




Comments

Federico Paolinelli
Grazie mille :-), cerco di darmi da fare come riesco, troppo buono a mettermi sullo stesso piano di Gabriele..
Ho visto la pull request, appena ho un attimo ci faccio un giro e la mergio, adesso sono un po' preso dall'arrivo di una figlia :-)

Grazie ancora per le (troppo) buone parole.
Alessandro Bellesia
Ciao Federico! Innanzitutto ti faccio i miei complimenti per l'ottimo progetto. Si tratta di una soluzione davvero molto completa e comoda perché già pronta out-of-the-box.

Grazie a te ed a Gabriele Mariotti praticamente l'Android Weekly è tutta italiana! Sono davvero molto contento.

Giocando un po con la libreria mi sono accorto che la funzione isServiceEnabled nel ServerInteractionHelper non funziona nel modo corretto. I numero di Services infatti risulta sempre 4 a prescindere dai servizi effettivamente impostati nel manifest dell'app.

Mi sono permesso di fare una piccola pull request su GitHub con la mia proposta di correzione!

Grazie mille ed ancora complimenti!

Saluti,
Alessandro.