Mengintegrasikan Retrofit dengan RxJava

1. Ikhtisar

Artikel ini berfokus pada cara mengimplementasikan Klien REST siap RxJava sederhana menggunakan Retrofit.

Kami akan membuat aplikasi contoh yang berinteraksi dengan GitHub API - menggunakan pendekatan Retrofit standar, lalu kami akan menyempurnakannya menggunakan RxJava untuk memanfaatkan keuntungan Pemrograman Reaktif.

2. Retrofit Polos

Mari pertama-tama buat contoh dengan Retrofit. Kami akan menggunakan GitHub API untuk mendapatkan daftar yang diurutkan dari semua kontributor yang memiliki lebih dari 100 kontribusi di repositori mana pun.

2.1. Dependensi Maven

Untuk memulai proyek dengan Retrofit, mari sertakan artefak Maven ini:

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

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

2.2. Antarmuka API

Mari buat antarmuka sederhana:

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

Metode listRepos () mengambil daftar repositori untuk pengguna tertentu yang diteruskan sebagai parameter jalur.

Metode listRepoContributers () mengambil daftar kontributor untuk pengguna dan repositori tertentu, keduanya diteruskan sebagai parameter jalur.

2.3. Logika

Mari mengimplementasikan logika yang diperlukan menggunakan objek Retrofit Call dan kode Java normal:

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. Mengintegrasikan Dengan RxJava

Retrofit memungkinkan kami menerima hasil panggilan dengan penangan khusus alih-alih objek Panggilan normal dengan menggunakan adaptor Panggilan Retrofit . Ini memungkinkan untuk menggunakan RxJava Observables and Flowables di sini.

3.1. Dependensi Maven

Untuk menggunakan adaptor RxJava, kita perlu menyertakan artefak Maven ini:

 com.squareup.retrofit2 adapter-rxjava 2.3.0 

Untuk versi terbaru, periksa adaptor-rxjava di repositori pusat Maven.

3.2. Daftarkan Adaptor 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. Antarmuka API

Pada titik ini, kita dapat mengubah jenis metode antarmuka yang dikembalikan untuk menggunakan Observable daripada Call . Kami dapat menggunakan tipe Rx lain seperti Observable , Flowable , Single , Maybe , Completable .

Mari kita ubah antarmuka API kita 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. Logika

Mari terapkan 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 kode sebelum dan sesudah menggunakan RxJava, kami menemukan bahwa itu telah diperbaiki dengan cara berikut:

  • Reaktif - karena data kami sekarang mengalir dalam aliran, ini memungkinkan kami untuk melakukan pemrosesan aliran asinkron dengan tekanan balik non-pemblokiran
  • Jelas - karena sifat deklaratifnya
  • Ringkas - seluruh operasi dapat direpresentasikan sebagai satu rantai operasi

Semua kode dalam artikel ini tersedia di GitHub.

Paket com.baeldung.retrofit.basic berisi contoh retrofit dasar sedangkan paket com.baeldung.retrofit. rx berisi contoh retrofit dengan integrasi RxJava.