Gokul Nath KP
Gokul Nath KP

Reputation: 15574

What is the best practices for retry mechanism while using Retrofit?

Problem Statement:

I'm using Retrofit in my application for API calls. Currently I've 20+ Retrofit Interfaces, with different Callbacks. Currently when app receives INVALID_SESSION_ID in anyone of these Interfaces (say UpdateUserAPI), I've to get new ACCESS_TOKEN, by invoking AccessTokenAPI.

Approach Suggested:

When app receives INVALID_SESSION_ID in Callback in UpdateUserAPI, invoke AccessTokenAPI to get new ACCESS_TOKEN. Upon receiving new ACCESS_TOKEN, post the actual call (with initial parameters in UpdateUserAPI) with new ACCESS_TOKEN. But this requires to save parameters in the class which implements UpdateUserAPI. Also I need to retry getting ACCESS_TOKEN only once, which should be handled.

What is the best approach to implement above requirement?

Upvotes: 0

Views: 5385

Answers (2)

Rehan Sarwar
Rehan Sarwar

Reputation: 1014

Create your own custom interceptor and check your token/session_id is valid or not. If your session_id is expired and then hit your updateUserAPI to get new id and set this id in header or where you want. Here is some code samples.

RefreshTokenInterceptor

    public static class RInterceptor implements Interceptor {
    @Override
    public Response intercept(Interceptor.Chain chain) throws IOException {
        Request request = chain.request();
        Response response = chain.proceed(request);
        try {
            if (response.code() == 410) {

                Response r = null;
                try {

                    r = makeTokenRefreshCall(request, chain);

                } catch (JSONException e) {
                    e.printStackTrace();
                }
                return r;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return response;
    }
}


  private static Response makeTokenRefreshCall(Request req, Interceptor.Chain chain) throws JSONException, IOException {
    /* fetch refreshed token, some synchronous API call, whatever Because we are responsible to return new response  */
    refreshTokenSync();
    Request newRequest;
    newRequest = req.newBuilder().header("authorization", NEW_TOKEN)/*.post(req.body())*/.build();
    return chain.proceed(newRequest);


}

RESTClient

 OkHttpClient okHttpClient = new OkHttpClient.Builder()
                    .readTimeout(50, TimeUnit.SECONDS)
                    .writeTimeout(55, TimeUnit.SECONDS)
                    .connectTimeout(50, TimeUnit.SECONDS)
                    .retryOnConnectionFailure(true)
                   .addInterceptor(new NetworkInterceptor())
                    .build();

Upvotes: 1

Raluca Lucaci
Raluca Lucaci

Reputation: 2153

Create your own TokenInterceptor

public class TokenInterceptor implements Interceptor 

Then set it to your okktpclient

Interceptor tokenInterceptor = new TokenInterceptor(provideUserLoginDao(appDatabase));
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .addInterceptor(tokenInterceptor)
                .writeTimeout(50, TimeUnit.SECONDS)
                .retryOnConnectionFailure(true)
                .build();

Useful information in this post also : Refreshing OAuth token using Retrofit without modifying all calls

Upvotes: 5

Related Questions