Лучшие практики использования Retrofit2 (несколько сервисов) - PullRequest
0 голосов
/ 03 декабря 2018

Я пишу приложение для Android с использованием Kotlin, интегрируя Retrofit2.

Насколько я понимаю (пожалуйста, поправьте меня, если я ошибаюсь), "традиционный" способ сделать это будет:

  1. Создание интерфейса, который включает определения методов для всех моих API.
  2. Передача его для модификации с помощью retrofit.create (), который реализует его для меня, и затем у меня есть доступдля всех них, используя функции из шага # 1

После просмотра this у меня возникает вопрос: лучше ли создавать отдельный интерфейс для каждого из моих запросов??

например, если у меня есть «LoginRequest», и я реализую его, как я покажу ниже («create», по сути, вызывает retrofit.create ()), в следующий раз, когда я захочу добавить / удалить только API, янужно добавить / удалить 1 файл, а не несколько мест (сам запрос, сервис из шага № 1 и все места, которые используют методы из шага № 2).С другой стороны, это заставило бы мое приложение «знать» retrofit2, и я не уверен, что это хорошая практика.

interface MyRequest {
    fun execute()
}

class LoginRequest (private val email: String, private val password: String) : MyRequest {
    interface LoginRequestService {
        @POST("login")
        fun emailLogin(
                @Body loginRequestBody: LoginRequestBody):
                retrofit2.Call<GetUserDetailsResponse>
    }

    override fun execute() {
        val requestBody = LoginRequestBody(email, password)
        val call = MyRequestManager.create(LoginRequestService::class.java).emailLogin(requestBody)
        MyRequestManager.executeCall(call)
    }
}

Ответы [ 2 ]

0 голосов
/ 03 декабря 2018

Способ, которым я делаю это в Java, - это 1 интерфейс для всех с отдельными запросами.

Внутри

public interface ApiInterface {
}

Я установил все URL в 1 месте для удобного редактирования позже.на

String Base_Url = "http://url.com/store/web/app_dev.php/api/";
String Base_Url_Channel = "http://url.com/store/web/app_dev.php/api/APP_STORE/";
String Image_URL_Online = "http://url.com/store/web/media/image/";

и для retrofit2 класса вызова метода

public class DataServiceGenerator {

    public static <S> S createService(Class<S> serviceClass) {

        String url = ApiInterface.Base_Url;
        Retrofit.Builder builder = new Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create())
                .baseUrl(url);

        OkHttpClient.Builder httpClient = new OkHttpClient.Builder()
                .readTimeout(15, TimeUnit.SECONDS)
                .connectTimeout(15, TimeUnit.SECONDS)
                .writeTimeout(25, TimeUnit.SECONDS);

        if (BuildConfig.DEBUG) {
            HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor()
                    .setLevel(HttpLoggingInterceptor.Level.BODY);
            httpClient.addInterceptor(interceptor);
            httpClient.addNetworkInterceptor(new StethoInterceptor()); // for debugging
        }
        builder.client(httpClient.build());
        Retrofit retrofit = builder.build();
        return retrofit.create(serviceClass);
    }
 }

Теперь для вызова API im используйте метод ниже в интерфейсе

@Multipart
@Headers("Accept: Application/json")
@POST("oauth/v2/token")
Call<Token_Model> token(
        @Part("client_id") RequestBody id,
        @Part("client_secret") RequestBody secret,
        @Part("grant_type") RequestBody username,
        @Part("username") RequestBody name,
        @Part("password") RequestBody password);

И для методасам:

Call<Token_Model> call = service.token(createPartFromString("13123khkjhfsdf"),
                createPartFromString("1asd234k234lkh24"),
                createPartFromString("password"), createPartFromString("api@example.com"), createPartFromString("test"));
        call.enqueue(new Callback<Token_Model>() {
            @Override
            public void onResponse(Call<Token_Model> call, retrofit2.Response<Token_Model> response) {
                if (response.isSuccessful()) {
                    token_model = response.body();
                    if (token_model != null) {
                        helper.setToken(token_model.getAccess_token());
                    }

                } else {
                    Toast.makeText(context, context.getString(R.string.failed_token), Toast.LENGTH_LONG).show();
                }
            }

            @Override
            public void onFailure(Call<Token_Model> call, Throwable t) {
                Toast.makeText(context, context.getString(R.string.failed_token), Toast.LENGTH_LONG).show();
            }
        });
0 голосов
/ 03 декабря 2018

было бы намного лучше, если бы вы следовали официальному руководству https://square.github.io/retrofit/

public interface GitHubService {
  @GET("users/{user}/repos")
  Call<List<Repo>> listRepos(@Path("user") String user);
}


Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    .build();



GitHubService service = retrofit.create(GitHubService.class);

Call<List<Repo>> repos = service.listRepos("octocat");

, тогда вы можете иметь один Singleton для Службы для упрощения, мне также нравится создавать интерфейсы для каждого вызова, как показано ниже,будет использоваться в любом классе, который я хочу.

interface IListRepos {
    fun listRepos(user: String, onResponse: (MutableList<Repo>?) -> Unit) {
        ServiceSingleton.client.create(GitHubService::class.java)
                .listRepos(user)
                .enqueue(object : Callback<MutableList<Repo>> {
                    override fun onResponse(call: Call<MutableList<Repo>>,
                                            response: retrofit2.Response<MutableList<Repo>>) {
                        onResponse(response.body())
                    }

                    override fun onFailure(call: Call<MutableList<Repo>>, t: Throwable) {
                        onResponse(null)
                    }
                })
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...