• Non classé
  • 0

RxTips – Retry

Problème récurrent lors d’appels de webservices : 401 UNAUTHORIZED

Et oui, le token a expiré, mais trop tard on l’a su une fois notre échange effectué, la galère de se reconnecter, puis relancer notre appel webservice avec les bons arguments tout ça tout ça…

Encore une fois, Rx viens nous sauver !

Exemple

Prenons l’exemple de la récupération d’une liste de contacts d’un membre.
Pour cela, nous appelons sur notre webservice (via retrofit ou autre) une méthode getContacts(username),
qui va nous retourner un Observable<List<User>>

webservice.getContacts("florent37")
          .subscribeOn(Schedulers.io())
          .observeOn(AndroidSchedulers.mainThread())
	  .subscribe(contacts -> {
	  	//afficher les contacts
	  });

Imaginons maintenant que notre webservice ait besoin dans les headers d’un token, donné par une méthode webservice.login
Et que ce token ait une durée de vie limitée (15min par exemple)

webservice.login(user, password)
          .subscribeOn(Schedulers.io())
          .observeOn(AndroidSchedulers.mainThread())
          .subscribe(token -> webservice.addTokenHeader(token)); 

Ici, webservice.addTokenHeader(token) va ajouter le token dans les headers de nos prochaines requêtes afin d’authentifier nos appels.

Notre webservice, comme 99.99% des webservices, nous renvoie une erreur 401 lorsque nous fournissons un mauvais token lors de nos appels (le 0.01% c’est le webservice que tu t’embête à implémenter pour ton client :D). Voyons ensemble comment relancer la connexion dans ce cas précis, puis relancer automatiquement la requête.

Retry !

Ajoutons un retryWhen à notre appel Rx. Il nous fournit un Observable de Throwable, sur lequel nous devrons utiliser un flatMap, qui contiendra notre appel à effectuer lors d’une erreur.

Je vais ici tester que mon throwable est une ApiException de type 401, dans ce cas je renverrai l’Observable webservice.login. Ici je relancerai la connexion, puis sauvegarderai le retour dans les headers du webservice.

Dans le cas contraire (ex: NullPointerException, IOException etc.) je renvoie juste Observable.error(throwable), ce qui ne relance pas de retry, et lance l’exception dans le onError de notre chaine d’observable.

webservice.getContacts("florent37")

          .retryWhen(errors -> 
                    errors.flatMap(throwable -> {
		            //si c'est une ApiException, de type 401, on se reconnecte et rééseaie
		            if(throwable instanceOf ApiException && ((ApiException)throwable).getStatusCode() == 401) {
		            	return webservice.login(user, password)
                                                  //sera appelé après avec le resultat de l'appel login(user, password)
                                                  .doOnNext(token -> webservice.addTokenHeader(token));
		            } else { //pour tous les autre cas, pas de retry
		            	return Observable.error(throwable);
		            }
		    })
		    
		     
	   )

	   .subscribeOn(Schedulers.io())
	   .observeOn(AndroidSchedulers.mainThread())

	   .subscribe(contacts -> {
	  	//afficher les contacts
	   });

Ici, le flux d’action est

getContacts("florent37") =>
=> *401* => 
=> errors.flatMap(ApiException(401)) => 
=> webservice.login(user, password) =>
=> webservice.addTokenHeader(token) => 
=> getContacts("florent37) =>
=> *contacts* 

On a bien relancé l’appel après un 401, et récupéré nos contacts 🙂

Un peu perdu en RxJava ? n’hésitez pas à aller faire un tour sur notre un article d’introduction sur RxJava , ainsi que celui détaillant l’utilisation des lambdas.

Petit rappel on vient de lancer une nouvelle rubrique sur le site, où vous pouvez découvrir des livres et des Goodies Android, allez-y faire un tour 😀

Vous aimerez aussi...

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Recevez un ebook GRATUIT !

Nous vous avons créé un ebook pour vous remercier de votre fidélité. Retrouvez les 10 librairies indispensables pour Android. Pour cela rien de plus simple vous avez juste à renseigner votre email, vous recevrez un mail de confirmation (pour que l'on vérifie que vous n'êtes pas un robot), il suffira de vous inscrire à la liste et vous recevrez l'Ebook quelques instant après (peut prendre un petit peu de temps car vous êtes beaucoup à le vouloir).
Votre adresse email
Secure and Spam free...