Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Removed volley and shifted api calls to retrofit #2896

Merged
merged 1 commit into from
Oct 21, 2019

Conversation

codedsun
Copy link
Contributor

Fixed #2895
Changes: Removes volley and shifts to retrofit

Screenshots of the change:

@auto-label auto-label bot added the Feature label Oct 19, 2019
@codedsun
Copy link
Contributor Author

@iamareebjamal @yashk2000 Please merge this!

Constants.IMGUR_IMAGE_UPLOAD_URL,
new Response.Listener<String>() {
ApiInterface retrofitClient =
RetrofitClient.getRetrofitClient(Urls.IMGUR_BASE_URL).create(ApiInterface.class);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be done once and stored in a static variable

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't because we need to have retrofit client with multiple base Url @iamareebjamal

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't because we need to have retrofit client with multiple base Url

Look at this, again
RetrofitClient.getRetrofitClient(Urls.IMGUR_BASE_URL)

Then look at this, again
RetrofitClient.getRetrofitClient(Urls.IMGUR_BASE_URL).create(ApiInterface.class)

And then read your comment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@iamareebjamal I have created client for Imgur but when I want to create for any other api I have to pass that api base url, for example pinterest.

We can't create a singleton class and store in static variable when we have multiple base url.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can never use ApiInterface for any other base URL or even any other endpoint. If you can, I'll change my name to whatever you say

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@iamareebjamal I know that we can create retrofit instance in a singleton class but this can be done when we have baseUrl only 1 through out the app. But as the pineterest account uses another base url I will have to create another singleton class for that base url as you suggested..

what i followed to not follow singleton approach and build the retrofit client with the base URL provided in the function itself.

ApiInterface is just an interface with different endpoints. You can invoke that function which corresponds to that baseUrl. It makes sense that with Imgur base URL i will not call uploadImagetoPinterest function and vice versa.

If i am wrong please guide me what shall I do.?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You want me to have multiple retrofit client in the app and mutiple interfaces for endpoints, I will go with this approach..

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Retrofit instance creation uses reflection and is expensive and should be done only once per application or activity, not on each function call

Copy link
Contributor Author

@codedsun codedsun Oct 19, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@iamareebjamal I will create the retrofit instance in the activity itself and should I pass the URL from here or keep that where the retrofit instance is created?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pass from here

/** Created by @codedsun on 19/Oct/2019 */
public class Urls {

public static final String IMGUR_BASE_URL = "https://api.imgur.com";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not useful as it is not reused

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's used while creating retrofit client

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://en.wikipedia.org/wiki/Reuse

This is an interesting read on this topic

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@iamareebjamal We have one place for keeping all the API's URL.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i will keep all the other accounts' url api endpoints here, if you want me to remove the file and use that directly in activity or something i will do that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a solid anti-pattern

@codedsun
Copy link
Contributor Author

codedsun commented Oct 19, 2019

@iamareebjamal What i m getting is to have multiple servicesclass (API Endpoint) for every baseUrl and no Urls file as they are not re-used anywhere?

@codedsun
Copy link
Contributor Author

@iamareebjamal You say to have a single retrofit instance for imgur, it's right but what shall I do when I have to hit with another base URL like for pinterest upload image, PR #2892. Then will I create another retrofit client. Then at runtime how will I change the base URL. Please define where I am wrong and what steps should i take to make the PR correct and merge ready.!

Thanks!

@iamareebjamal
Copy link
Member

iamareebjamal commented Oct 19, 2019

You have to create another retrofit instance for another base URL anyway, so I don't get your point at all. Why are you creating the retrofit instance and the service class both on each call of the function?

Imagine retrofit instance and service class instantiation takes 3 seconds to complete for the sake of argument. And rest of the method takes 1 sec. Your method will take 4 second each time and my method will take 4 second for first time and 1 second for every other time.

You say to have a single retrofit instance for imgur, it's right but what shall I do when I have to hit with another base URL like for pinterest upload image

Then you have to create another retrofit instance in any case! It has nothing to do with the fact that you are creating the service in method each time, instead of 1 time. You may use singleton or not, that is your choice. Both of those approaches will not save you from having to create another retrofit instance for pinterest upload

@codedsun
Copy link
Contributor Author

@iamareebjamal Convinced, thankyou for such detail. Please check now

@codedsun
Copy link
Contributor Author

@iamareebjamal check now

import retrofit2.http.POST;

/** Created by @codedsun on 19/Oct/2019 */
public interface ImgurApiInterface {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public interface ImgurApiInterface {
public interface ImgurApi {

import retrofit2.http.Header;
import retrofit2.http.POST;

/** Created by @codedsun on 19/Oct/2019 */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove

@codedsun
Copy link
Contributor Author

@iamareebjamal Check!

@@ -8,7 +8,6 @@
public static final int REQUEST_SHARE_RESULT = 50;
public static final String SHARE_RESULT = "share_result";

public static final String IMGUR_IMAGE_UPLOAD_URL = "https://api.imgur.com/3/image/";
public static String IMGUR_HEADER_CLIENt = "Client-ID";
public static String IMGUR_HEADER_USER = "Bearer";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If these are used in one place only, move them to that place as well

import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

/** Created by @codedsun on 19/Oct/2019 */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are automatically generated. Ok will remove

HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.level(HttpLoggingInterceptor.Level.BODY);
httpClient.interceptors().add(interceptor);
return httpClient;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is same for every instance, so it should be cached

private static OkHttpClient.Builder httpClient() {
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.level(HttpLoggingInterceptor.Level.BODY);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Level BODY is too verbose

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@iamareebjamal Just used for development purpose, will add check of debug and production here from buildconfig

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BODY is too verbose even for debug. Stetho should be used instead

@codedsun codedsun force-pushed the Retrofit branch 2 times, most recently from ad10f3f to 567d530 Compare October 20, 2019 13:10

@POST("/image")
Call<JsonElement> uploadImageToImgur(
@Header("Authorization") String authorization, @Body ArrayMap<String, String> body);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change body to a class

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Means?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not arraymap?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because it's java, not python or JS

public interface ImgurApi {

@POST("/image")
Call<JsonElement> uploadImageToImgur(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JsonElement to as well

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

? Response to a class? why?

Copy link
Contributor Author

@codedsun codedsun Oct 20, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we should have a class for every API response? why should we follow this approach?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the extension of the file

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i will change but JsonElement is also a class present under package com.google.gson;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Obviously, it is. You can even use ArrayList without type parameters to make it like Python and JS. You can do anything in Java that you can do in Python or JS, but we want type safety

@codedsun
Copy link
Contributor Author

@iamareebjamal Review !

public static final String EXTRA_OUTPUT = "extra_output";
public static String IMGUR_HEADER_CLIENT = "Client-ID";
public String IMGUR_HEADER_USER = "Bearer";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Group IMGUR fields together

this.data = data;
}

public class Data {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public class Data {
public static class Data {

@@ -155,6 +150,9 @@
OnRemoteOperationListener,
RecyclerItemClickListner.OnItemClickListener {

private static final String IMGUR_BASE_URL = "https://api.imgur.com/3/";
public static String IMGUR_HEADER_CLIENT = "Client-ID";
public String IMGUR_HEADER_USER = "Bearer";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are these public and not static final?

@@ -155,6 +150,9 @@
OnRemoteOperationListener,
RecyclerItemClickListner.OnItemClickListener {

private static final String IMGUR_BASE_URL = "https://api.imgur.com/3/";
public static String IMGUR_HEADER_CLIENT = "Client-ID";
public String IMGUR_HEADER_USER = "Bearer";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public String IMGUR_HEADER_USER = "Bearer";
private static final String IMGUR_HEADER_USER = "Bearer";

@@ -155,6 +150,9 @@
OnRemoteOperationListener,
RecyclerItemClickListner.OnItemClickListener {

private static final String IMGUR_BASE_URL = "https://api.imgur.com/3/";
public static String IMGUR_HEADER_CLIENT = "Client-ID";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public static String IMGUR_HEADER_CLIENT = "Client-ID";
private static final String IMGUR_HEADER_CLIENT = "Client-ID";

@codedsun
Copy link
Contributor Author

@iamareebjamal are we good to go now?

@codedsun
Copy link
Contributor Author

@iamareebjamal Thank you for approval and efforts!

@iamareebjamal iamareebjamal merged commit 9d671ac into fossasia:development Oct 21, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Move to Retrofit
2 participants