レトロフィットとRxJavaの統合
1概要
この記事では、http://square.github.io/retrofit/[Retrofit]を使って簡単なhttps://github.com/ReactiveX/RxJava[RxJava-ready]RESTクライアントを実装する方法に焦点を当てます。
標準のRetrofitアプローチを使用してGitHub APIと対話するサンプルアプリケーションを作成し、次にRxJavaを使用してそれを強化してReactive Programmingの利点を活用します。
2プレーンレトロフィット
最初にRetrofitを使って例を作りましょう。 GitHub APIを使用して、任意のリポジトリに100を超える貢献がある貢献者すべてのソートリストを取得します。
2.1. Mavenの依存関係
Retrofitを使ってプロジェクトを開始するには、次のMavenアーティファクトを含めます。
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>retrofit</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>converter-gson</artifactId>
<version>2.3.0</version>
</dependency>
最新版については、https://search.maven.org/classic/#search%7C1%7Cg%3A%22com.squareup.retrofit2%22%20AND%20a%3A%22retrofit%22[をご覧ください。後付け]およびhttps://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22com.squareup.retrofit2%22%20AND%20a%3A%22converter-gson%22[converter-gson]Maven Centralリポジトリで。
2.2. APIインターフェース
簡単なインターフェースを作りましょう。
public interface GitHubBasicApi {
@GET("users/{user}/repos")
Call<List> listRepos(@Path("user") String user);
@GET("repos/{user}/{repo}/contributors")
Call<List> listRepoContributors(
@Path("user") String user,
@Path("repo") String repo);
}
listRepos()
メソッドは、パスパラメータとして渡された特定のユーザーのリポジトリのリストを取得します。
listRepoContributers()
メソッドは、指定されたユーザーとリポジトリの貢献者のリストを取得します。両方ともパスパラメータとして渡されます。
2.3. 論理
Retrofit
Call
オブジェクトと通常のJavaコードを使用して必要なロジックを実装しましょう。
class GitHubBasicService {
private GitHubBasicApi gitHubApi;
GitHubBasicService() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
gitHubApi = retrofit.create(GitHubBasicApi.class);
}
List<String> getTopContributors(String userName) throws IOException {
List<Repository> 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<Contributor> getContributors(String userName, Repository repo) {
List<Contributor> 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
との統合
Retrofitは、Retrofit
Call
アダプタを使用して、通常の
Call
オブジェクトではなくカスタムハンドラを使用して呼び出し結果を受け取ることができます。これはここでRxJava
Observables
と
Flowables
を使うことを可能にします。
3.1. Mavenの依存関係
RxJavaアダプターを使用するには、このMaven成果物を含める必要があります。
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>adapter-rxjava</artifactId>
<version>2.3.0</version>
</dependency>
最新版はhttps://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22com.squareup.retrofit2%22%20AND%20a%3A%22adapter-rxjava%22[adapter Maven中央リポジトリの-rxjava]。
3.2. RxJava通話アダプタの登録
RxJavaCallAdapter
をビルダーに追加しましょう。
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
3.3. APIインターフェース
この時点で、
Call <…>
ではなく
Observable <…>
を使用するようにインターフェイスメソッドの戻り型を変更できます。
Observable
、
Flowable
、
Single
、
Maybe
、
Completable
などの他のRxタイプを使用することもできます。
Observable
を使用するようにAPIインターフェースを変更しましょう。
public interface GitHubRxApi {
@GET("users/{user}/repos")
Observable<List<Repository>> listRepos(@Path("user") String user);
@GET("repos/{user}/{repo}/contributors")
Observable<List<Contributer>> listRepoContributors(
@Path("user") String user,
@Path("repo") String repo);
}
3.4. 論理
RxJavaを使って実装しましょう。
class GitHubRxService {
private GitHubRxApi gitHubApi;
GitHubRxService() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
gitHubApi = retrofit.create(GitHubRxApi.class);
}
Observable<String> 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を使用する前後のコードを比較すると、次のように改善されていることがわかりました。
-
反応的 – データがストリームに流れるようになったので、次のことが可能になります。
ノンブロッキングバックプレッシャによる非同期ストリーム処理
** 明確 – 宣言的な性質のため
-
簡潔 – 操作全体を1つの操作として表すことができます。
鎖
この記事のすべてのコードはhttps://github.com/eugenp/tutorials/tree/master/libraries[GitHubで利用できます。]
パッケージ
com.baeldung.retrofit.basic
に基本的なレトロフィットの例が含まれ、パッケージ
_com.baeldung.retrofit .
_
rxにRxJava統合のレトロフィットの例が含まれています。