Android Retrofit Design Patterns

What design pattern retrofit uses and how does it use it in Android?

This is by no means a comprehensive answer, but too long for a comment.

I wouldn't say it has a single pattern. You can definitely find several there, i.e., Builder for when you are building the retrofit instance.

I guess one could say the main pattern is the Proxy Pattern. To the best of my knowledge Retrofit uses this to implement the api interface we define.

It creates a proxy object for the interface and every time the methods get called, it will go through the annotations and build the correct http request. From our perspective it feels like we're calling an implementation, but it's actually a proxy.

I suppose one could say that for the interceptors it uses Chain of Responsibility. However, the interceptors are part of a dependency - OkHttp - rather than retrofit itself.

As for the question "How does it use it in Android?" - I'd say no different than in any other place. Retrofit's design patterns are not specific for Android and would work everywhere the same.

Android Retrofit Design Patterns

I usually use singleton pattern with following structure :

first define ServiceHelper like following :

public class ServiceHelper {

private static final String ENDPOINT = "http://test.com";

private static OkHttpClient httpClient = new OkHttpClient();
private static ServiceHelper instance = new ServiceHelper();
private IPlusService service;

private ServiceHelper() {

Retrofit retrofit = createAdapter().build();
service = retrofit.create(IPlusService.class);
}

public static ServiceHelper getInstance() {
return instance;
}

private Retrofit.Builder createAdapter() {

httpClient.setReadTimeout(60, TimeUnit.SECONDS);
httpClient.setConnectTimeout(60, TimeUnit.SECONDS);
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
httpClient.interceptors().add(interceptor);

return new Retrofit.Builder()
.baseUrl(ENDPOINT)
.client(httpClient)
.addConverterFactory(GsonConverterFactory.create());
}

public Call<List<CategoryModel>> getAllCategory() {
return service.getAllCategory();
}

Then put all of your services in IService (in my case it's IPlusService)

    public interface IPlusService {
//@Headers( "Content-Type: application/json" ) in Post method may use this
@GET("/api/category")
Call<List<CategoryModel>> getAllCategory();
}

Then call your singleton like below in your activity/fragment :

ServiceHelper.getInstance().getAllCategory().enqueue(new Callback<List<CategoryModel>>() {
@Override
public void onResponse(Response<List<CategoryModel>> response, Retrofit retrofit) {
processResponse(response);
}

@Override
public void onFailure(Throwable t) {
processResponse(null);
}
});

Design pattern for retrofit interface

Make your interceptor look like this:

public class TokenInterceptor implements Interceptor {

private String token;

public String getToken() {
return token;
}

@Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();

// Request customization: add request headers
Request.Builder requestBuilder = original.newBuilder()
.header("Cache-Control", "no-cache")
.header("Accept", "application/json")
.method(original.method(), original.body());
if (getToken() != null) {
requestBuilder.header("Authorization", "Bearer " + AmzToken);
}
Request request = requestBuilder.build();
return chain.proceed(request);
}

public void setToken(String token) {
this.token = token;
}
}

Add it to you OkHttp client and keep reference to this interceptor.
Now you don't have to call createService() after each token change. Just change token in interceptor via interceptor.setToken()

Android: how to use Code to interface design pattern to have multiple implementations of network call libraries(Retrofit or volley)

1) Methods with callbacks should have no return type. You return null anyway, so make them void.

2) You will eventually need the response back in the UI to update your views, so You should pass the callback as a Callback class, not some String callback.

3) That private field does not need updated for every call to your methods.

4) You don't need an Activity to make a network request (back to point 2, I guess)

5) I'm pretty sure Retrofit uses annotations to handle the URL, so not sure I see the purpose of the parameter at getDataFromServer(url).


Your updated code would look like this.

Note: This is not a showcase of "programming an interface", or really any "design pattern", it is simply "clean code" (IMHO).

Retrofit already enforces the "program an interface" pattern, anyway though the Retrofit.create method.

public class NetworkCallsRetrofitImpl implements NetworkCallsApi{

private final Retrofit retrofit;

public NetworkCallsRetrofitImpl() {
retrofit = new Retrofit.Builder()
.baseUrl(StringConstants.ROOT_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}

public void getDataFromServer(String url, Callback<ResponseBody> cb) {
retrofit.create(RetrofitApi.class)
.getDataFromServer(url)
.enqueue(cb);
}
}

// This method seems really pointless, by the way... 
public void getDataFromServer(String url, Call<ResponseBody> callback){
networkCallsimpl.getDataFromServer(url,callback);
}

public class StatusFragment extends Fragment implements Callback<ResponseBody> {   

private ServiceCalls serviceCalls;

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Setting the implementation
serviceCalls = ServiceCalls.getInstance();
serviceCalls.setNetworkCallsimpl(new NetworkCallsRetrofitImpl());
}

private void updateStatus() {
serviceCalls.getDataFromServer("http://site.example/status", this);
}

@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
String response = response.body().toString();
Toast.makeText(getActivity(), response, TOAST.LENGTH_SHORT).show();
}

@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e("err", t.getMessage());
}
}

What can be a good way to call network class other than an activity in android?

For Start if you have to create an app from scratch, possibly try to follow one architecture since you are looking for network calls, Sample Image

You can Use MVVM for best practice and it also handle the api request in best way possible As you can see from figure,
This architecture, basically separates the view(UI) from view Model(logic of view)

It's up to you how you want to develop the app, means you can skip the repository and handle the network calls in view models or else you can create a single repository class and place all the network related stuffs i.e: network call and similar stuff.

reference tutorial : https://learntodroid.com/consuming-a-rest-api-using-retrofit2-with-the-mvvm-pattern-in-android/

Best design pattern for data model in restrofit rest android app which json data

This is what I do with Retrofit. Just use jsonschema2pojo to generate your POJO's (model classes). This will have all your getters and setters and serialized data for you to use and manipulate as you wish.

Let's say you're retrieving a Data objects. When you retrieve data with Retrofit, just throw them into a List<Data>. Something like the following code:

public interface DataService{
@GET("/{user}/data")
List<Data> listData(@Path("user") String user);
}

RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint("https://your.url.com")
.build();

DataService service = restAdapter.create(DataService.class);

List<Data> datas = service.listData("your_parameter");

From a design standpoint, I find this to be the most elegant way because your POJOs should change as frequently as the API changes (that is, very infrequently). As such, it's OK to auto-generate your code and just have this black-box to reference. The best code is the code you don't have to write. Be careful to not over-architect.

Android MVP with RxAndroid + Retrofit

As you pointed the RxJava functionality defines a use case of your model layer so it would be placed in an interactor of this layer. You can create a different interactor for each use case. Let's say you are pulling a list of users from your server, this would be a use case and an interactor that will have the RxJava/Retrofit Observable.

Then you will have a Presenter with an Observer in it which is interested in this users list, so it will be subscribed to that Observable.

And finally when this Observer in has all the data from the Observable (onCompleted), it will transform this data (if needed it) and pass to the View which will be just in charge of display it.



Related Topics



Leave a reply



Submit