Divide Retrofit service declaration into multiple interfaces

retrofit multiple endpoints
retrofit kotlin
retrofit basic authentication
retrofit multiple base url
api declarations must be interfaces
multiple api call in retrofit android
retrofit spring boot
retrofit best practices

I am creating an app linking to an API with about 265 methods to it. I would very much like to break apart the declaration of these APIs into multiple files to keep them organized and accessible. However Retrofit explicitly disallows combining interfaces through extension.

java.lang.IllegalArgumentException: Interface definitions must not extend other interfaces.

I had been trying to declare it as follows.

public interface ApiService extends ProfileService, AccountService {
    // Empty interface, methods divided into other services
}

public interface ProfileService {
    @GET("/api/v1/protected/profile")
    public void getProfile(Callback<Profile> callback);

    ...
}

public interface AccountService {
    @GET("/api/v1/protected/account")
    public void getAccount(Callback<Account> callback);


    ...
}

There is a discussion about this issue on a pull request. The library authors have decided that extending interfaces like this is not in the spirit of the library. https://github.com/square/retrofit/pull/676

Jake Wharton (the author) says that "Retrofit favors composition." And in response to "Do you really have a single adapter with a ton of proxies?", "Yes. They are generated from a service declaration in protos. One interface per service."

I've been reading about composition vs inheritance and fail to grasp how to achieve the goal of breaking up the declaration.

How can I divide the interface declaration up? Is there a best practice that I'm missing?

Thank you.

Just create separate interfaces.

public interface ProfileService {

  /* ... */
}

public interface AccountService {

  /* ... */
}

ProfileService profileService = mRestAdapter.create(ProfileService.class);
AccountService accountService = mRestAdapter.create(AccountService.class);

Divide Retrofit service declaration into multiple interfaces, I am creating an app linking to an API with about 265 methods to it. I would very much like to break apart the declaration of these APIs into multiple files to keep� Why wouldn't you just split those up into multiple interfaces? Clearly they have semantic meaning based on the variant so codify that meaning into the type system. On Tue, Apr 24, 2018 at 10:47 AM Bartosz Wyspiański < ***@***.***> wrote: To be honest, i think this is very nice feature.

I am still experimenting on if this is the best way to go about using this but here is what I have so far. It may not be the cleanest approach yet but I am liking it versus one service with 100 api calls. Splits it up a little and makes it easier to read.

This is the main class to access the data. I have seen a lot separate out the two static methods I have into a separate class but i just included it as one.

public class RetrofitApi {
   public enum ApiTypes {
        USER_API(UserApi.class);

        private final Class<? extends RetrofitApi> apiClass;
        ApiTypes(Class<? extends RetrofitApi> apiClass){
            this.apiClass = apiClass;
        }
        Class<? extends RetrofitApi> getApiType() {return this.apiClass;}
    }
    public static  <T> T getApi(RetrofitApi.ApiTypes type) {
        try {
            return (T) type.getApiType().newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }
    public static RestAdapter getRestAdapter() {
        RestAdapter restAdapter = new RestAdapter.Builder()
            .setEndpoint(BASE_URL)
            .setLogLevel(retrofit.RestAdapter.LogLevel.HEADERS)
            .build();
        return restAdapter;
    }
}

Each service has its own api. This does mean more classes. I split them into api, service, model. API is the high level that you will use and expose. Service is more or less just a list of calls. And Model is the model (data object).

public class UserApi extends RetrofitApi {

    private UserService service;

    public UserApi() {
        RestAdapter restAdapter =
                RetrofitApi.getRestAdapter();
        service = restAdapter.create(UserService.class);
    }

    public void login(String email,
                      String password,
                      Callback<User> callback) {
        service.login(email, password, callback);
    }
}

Service is the interface. Its more or less just a list of api calls that get exposed.

public interface UserService {

    @GET("/api/users/login")
    void login(@Query("email") String email,
                   @Query("password") String password,
                   Callback<User> callback);
}

Then to use it.

 UserApi api = RetrofitApi.getApi(RetrofitApi.ApiTypes.USER_API);
 api.login(email,password,callback);

And here is the project structure. To me, it seems clean at the moment. I am sure it will end up getting big when I have 20+ of them. But it might be a little cleaner when those 20 have multiple calls.

Allow to configure retrofit to allow API interfaces to extend interfaces , Why wouldn't you just split those up into multiple interfaces? Clearly they Allow service interfaces to extend other interfaces #3145. Merged. Retrofit is the class through which your API interfaces are turned into callable objects. By default, Retrofit will give you sane defaults for your platform but it allows for customization. Converters. By default, Retrofit can only deserialize HTTP bodies into OkHttp's ResponseBody type and it can only accept its RequestBody type for @Body.

How do you use Retrofit with multiple interfaces? : androiddev, I have a large API (100+ methods) that I want to put into 7 or 8 files. a single master interface that implements all the othersso how can I create a Retrofit It' d be much better split into UserService , GroupService , etc. I will if that's the only way to do it; I would just prefer to have the 100+ declarations split up if possible. The official Retrofit page describes itself as. A type-safe REST client for Android and Java. Retrofit turns your REST API into a Java interface. It uses annotations to describe HTTP requests, URL parameter replacement and query parameter support is integrated by default.

How to set up networking in your Android app with Retrofit-RxJava , Once you go through the above two, you are ready to move forward with This will divide the entire width of your screen into 3 columns in the Many people like to keep their View and Presenter interfaces in different files, but according to Setting up an API Service interface which defines our endpoints. Once you've a deep understanding of Retrofit, writing complex requests (e.g., OAuth authentication) will be done in a few minutes. Invest time to fully understand Retrofit's principles. It'll pay off multiple times in the future! Our book offers you a fast and easy way to get a full overview over Retrofit.

Create reactive mobile apps in a fraction of the time, Realm implements Closeable to take care of native memory deallocation and file (both RealmResults and RealmList implement this interface) to standard UI widgets. If you have two or more RealmModule s, you will have to split the declarations out of the box, but note that Retrofit does not automatically add objects to� The implementation of interface’s members will be given by the class who implements the interface implicitly or explicitly. C# allows the implementation of multiple interfaces with the same method name. To understand how to implement multiple interfaces with the same method name we take an example.

Retrofit2, Retrofit turns your REST API into a Java interface. There's a lot going on here in a pretty compact space so let's break it down: public interface Service { @ POST("device") Call<Device> getDevice(@Body GetDeviceRequest Interface declaration for downloading a file Upload multiple file using Retrofit as multipart. Registering a single implementation as multiple services. It's pretty common to see classes that implement multiple interfaces, for example: public interface IBar {} public interface IFoo {} public class Foo: IFoo, IBar {} Lets write a quick test to see what happens if we register the class against both interfaces using the ASP.NET Core DI

Comments
  • Best practice that I'm missing then. :) Is there a recommended way of accessing the different services? At the moment I have a static RestClient object and call App.getRestClient().getProfileService().getProfile(new Callback<LinkedInResponse>() {...} ); I suppose using Dagger is probably the elegant way.
  • You can use a simple Factory.
  • Ok. I'll give that a shot. Thank you.