Интегриране на модернизация с RxJava

1. Общ преглед

Тази статия се фокусира върху това как да внедрите прост RXJava-готов REST клиент, използващ Retrofit.

Ще създадем примерно приложение, взаимодействащо с API на GitHub - използвайки стандартния подход за модернизация и след това ще го подобрим с помощта на RxJava, за да използваме предимствата на реактивното програмиране.

2. Обикновена модернизация

Нека първо изградим пример с Retrofit. Ще използваме API на GitHub, за да получим сортиран списък на всички сътрудници, които имат повече от 100 приноса във всяко хранилище.

2.1. Зависимости на Maven

За да започнем проект с модернизация, нека включим тези артефакти на Maven:

 com.squareup.retrofit2 retrofit 2.3.0   com.squareup.retrofit2 converter-gson 2.3.0 

За най-новите версии погледнете модернизацията и конвертора-gson в хранилището на Maven Central.

2.2. API интерфейс

Нека създадем прост интерфейс:

public interface GitHubBasicApi { @GET("users/{user}/repos") Call listRepos(@Path("user") String user); @GET("repos/{user}/{repo}/contributors") Call listRepoContributors( @Path("user") String user, @Path("repo") String repo); }

Методът listRepos () извлича списък с хранилища за даден потребител, предаден като параметър на пътя.

Методът listRepoContributers () извлича списък на сътрудници за даден потребител и хранилище, и двете предадени като параметри на пътя.

2.3. Логика

Нека внедрим необходимата логика, като използваме обекти за модернизиране на обаждания и нормален Java код:

class GitHubBasicService { private GitHubBasicApi gitHubApi; GitHubBasicService() { Retrofit retrofit = new Retrofit.Builder() .baseUrl("//api.github.com/") .addConverterFactory(GsonConverterFactory.create()) .build(); gitHubApi = retrofit.create(GitHubBasicApi.class); } List getTopContributors(String userName) throws IOException { List repos = gitHubApi .listRepos(userName) .execute() .body(); repos = repos != null ? repos : Collections.emptyList(); return repos.stream() .flatMap(repo -> getContributors(userName, repo)) .sorted((a, b) -> b.getContributions() - a.getContributions()) .map(Contributor::getName) .distinct() .sorted() .collect(Collectors.toList()); } private Stream getContributors(String userName, Repository repo) { List contributors = null; try { contributors = gitHubApi .listRepoContributors(userName, repo.getName()) .execute() .body(); } catch (IOException e) { e.printStackTrace(); } contributors = contributors != null ? contributors : Collections.emptyList(); return contributors.stream() .filter(c -> c.getContributions() > 100); } }

3. Интегриране с RxJava

Модернизацията ни позволява да получаваме резултати от обаждания с персонализирани манипулатори вместо обичайния обект на повикване, като използваме адаптери за модернизиране на повиквания . Това дава възможност да се използва RxJava наблюдаеми и Течните тук.

3.1. Зависимости на Maven

За да използваме адаптер RxJava, трябва да включим този артефакт на Maven:

 com.squareup.retrofit2 adapter-rxjava 2.3.0 

За най-новата версия, моля, проверете adapter-rxjava в централното хранилище на Maven.

3.2. Регистрирайте RxJava Call Adapter

Нека добавим RxJavaCallAdapter към конструктора:

Retrofit retrofit = new Retrofit.Builder() .baseUrl("//api.github.com/") .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .build();

3.3. API интерфейс

На този етап можем да променим типа на връщане на метода на интерфейса, за да използваме Observable, а не Call . Можем да използваме други Rx типове като Observable , Flowable , Single , Maybe , Completable .

Нека модифицираме нашия интерфейс на API, за да използваме Observable :

public interface GitHubRxApi { @GET("users/{user}/repos") Observable
    
      listRepos(@Path("user") String user); @GET("repos/{user}/{repo}/contributors") Observable
     
       listRepoContributors( @Path("user") String user, @Path("repo") String repo); }
     
    

3.4. Логика

Нека го приложим с помощта на RxJava:

class GitHubRxService { private GitHubRxApi gitHubApi; GitHubRxService() { Retrofit retrofit = new Retrofit.Builder() .baseUrl("//api.github.com/") .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .build(); gitHubApi = retrofit.create(GitHubRxApi.class); } Observable getTopContributors(String userName) { return gitHubApi.listRepos(userName) .flatMapIterable(x -> x) .flatMap(repo -> gitHubApi.listRepoContributors(userName, repo.getName())) .flatMapIterable(x -> x) .filter(c -> c.getContributions() > 100) .sorted((a, b) -> b.getContributions() - a.getContributions()) .map(Contributor::getName) .distinct(); } }

4. Заключение

Сравнявайки кода преди и след използване на RxJava, установихме, че той е подобрен по следните начини:

  • Реактивен - тъй като данните ни сега текат в потоци, това ни позволява да извършваме асинхронна обработка на потоци с неблокиращо обратно налягане
  • Ясно - поради декларативния му характер
  • Кратко - цялата операция може да бъде представена като една операционна верига

Целият код в тази статия е достъпен в GitHub.

Пакетът com.baeldung.retrofit.basic съдържа основния пример за модернизация, докато пакетът com.baeldung.retrofit. rx съдържа примера за модернизация с интеграция на RxJava.