Mengintegrasikan Retrofit dengan RxJava

1. Gambaran keseluruhan

Artikel ini memfokuskan pada cara melaksanakan REST Client RxJava yang mudah menggunakan Retrofit.

Kami akan membina aplikasi contoh yang berinteraksi dengan GitHub API - menggunakan pendekatan Retrofit standard, dan kemudian kami akan memperbaikinya menggunakan RxJava untuk memanfaatkan kelebihan Pengaturcaraan Reaktif.

2. Retrofit biasa

Mari kita mulakan contoh dengan Retrofit. Kami akan menggunakan API GitHub untuk mendapatkan senarai semua penyumbang yang mempunyai lebih daripada 100 sumbangan di repositori.

2.1. Ketergantungan Maven

Untuk memulakan projek dengan Retrofit, mari sertakan artifak Maven berikut:

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

Untuk versi terkini, lihat retrofit dan converter-gson di repositori Maven Central.

2.2. Antaramuka API

Mari buat antara muka mudah:

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); }

Kaedah listRepos () mengambil senarai repositori untuk pengguna tertentu yang dilewatkan sebagai parameter jalan.

Kaedah listRepoContributers () mengambil senarai penyumbang untuk pengguna tertentu dan repositori, keduanya dilewatkan sebagai parameter jalan.

2.3. Logik

Mari kita laksanakan logik yang diperlukan menggunakan objek Retrofit Call dan kod Java biasa:

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. Bersepadu dengan RxJava

Retrofit memungkinkan kita menerima hasil panggilan dengan pengendali khusus dan bukan objek Panggilan biasa dengan menggunakan penyesuai Panggilan Retrofit . Ini menjadikan ia mungkin untuk menggunakan RxJava cerap dan Flowables sini.

3.1. Ketergantungan Maven

Untuk menggunakan penyesuai RxJava, kita perlu memasukkan artifak Maven ini:

 com.squareup.retrofit2 adapter-rxjava 2.3.0 

Untuk versi terkini sila periksa adapter-rxjava di repositori pusat Maven.

3.2. Daftar Adapter Panggilan RxJava

Mari tambahkan RxJavaCallAdapter ke pembangun:

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

3.3. Antaramuka API

Pada ketika ini, kita dapat mengubah jenis kaedah antara muka pengembalian untuk menggunakan Observable daripada Call . Kita boleh menggunakan jenis Rx lain seperti diperhatikan , flowable , Single , Mungkin , Completable .

Mari ubah suai antara muka API kami untuk menggunakan 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. Logik

Mari laksanakan dengan menggunakan 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. Kesimpulan

Membandingkan kod sebelum dan sesudah menggunakan RxJava, kami mendapati bahawa kod tersebut telah diperbaiki dengan cara berikut:

  • Reaktif - kerana data kami kini mengalir dalam aliran, ini membolehkan kami melakukan pemprosesan aliran tak segerak dengan tekanan belakang yang tidak menyekat
  • Jelas - kerana sifatnya yang bersifat deklaratif
  • Ringkas - keseluruhan operasi dapat ditunjukkan sebagai satu rangkaian operasi

Semua kod dalam artikel ini terdapat di GitHub.

Pakej com.baeldung.retrofit.basic mengandungi contoh retrofit asas manakala pakej com.baeldung.retrofit. rx mengandungi contoh retrofit dengan integrasi RxJava.