Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
はやい・やすい・うまい!スタートアップでも使える Retrofit + RxJava で瞬間A...
Search
Fumihiko Shiroyama
July 14, 2017
Technology
2
630
はやい・やすい・うまい!スタートアップでも使える Retrofit + RxJava で瞬間APIクッキングレシピ
はやい・やすい・うまい!スタートアップでも使える Retrofit + RxJava で瞬間APIクッキングレシピ
Fumihiko Shiroyama
July 14, 2017
Tweet
Share
More Decks by Fumihiko Shiroyama
See All by Fumihiko Shiroyama
The world of Android wireless communications without Internet
srym
1
140
AWS Device FarmとCircleCIでAndroidのUIテストを自動化しよう
srym
1
5.1k
Spring BootをKotlinで作成しAmazon Elastic Container Service (ECS) で稼働させる
srym
6
2k
iOSDC_2019_DeviceFarm.pdf
srym
8
20k
世界で戦うエンジニアになるために_公開用.pdf
srym
18
45k
Unit Testing in a Nutshell - DroidKaigi 2018
srym
11
15k
Clean Architecture & TDD
srym
1
3.8k
I/O 2017 Short Report
srym
0
310
Mock Partially using Dagger
srym
0
660
Other Decks in Technology
See All in Technology
ペアーズにおけるData Catalog導入の取り組み
hisamouna
0
270
30 代子育て SRE が考える SRE ナレッジマネジメントの現在と将来
kworkdev
PRO
0
200
やさしいMCP入門
minorun365
PRO
146
94k
ウォンテッドリーにおける Platform Engineering
bgpat
0
180
All You Need Is Kusa 〜Slackデータで始めるデータドリブン〜
jonnojun
0
140
バックオフィス向け toB SaaS バクラクにおけるレコメンド技術活用 / recommender-systems-in-layerx-bakuraku
yuya4
2
220
SRE NEXT CfP チームが語る 聞きたくなるプロポーザルとは / Proposals by the SRE NEXT CfP Team that are sure to be accepted
chaspy
1
560
2025年春に見直したい、リソース最適化の基本
sogaoh
PRO
0
460
YOLOv10~v12
tenten0727
3
840
FinOps_Demo
tkhresk
0
130
TopAppBar Composableをカスタムする
hunachi
0
170
「家族アルバム みてね」を支えるS3ライフサイクル戦略
fanglang
4
650
Featured
See All Featured
Why Our Code Smells
bkeepers
PRO
336
57k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
129
19k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
31
1.1k
Gamification - CAS2011
davidbonilla
81
5.2k
Adopting Sorbet at Scale
ufuk
76
9.3k
Building Adaptive Systems
keathley
41
2.5k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
233
17k
The Straight Up "How To Draw Better" Workshop
denniskardys
232
140k
VelocityConf: Rendering Performance Case Studies
addyosmani
328
24k
A Modern Web Designer's Workflow
chriscoyier
693
190k
The World Runs on Bad Software
bkeepers
PRO
67
11k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
13
660
Transcript
͍ɾ͍͢ɾ͏·͍ʂ ελʔτΞοϓͰ͑Δ Retrofit + RxJava ͰॠؒAPIΫο ΩϯάϨγϐ @fushiroyama
About Me • Fumihiko Shiroyama • Android App Developer •
https://github.com/srym
How to implement REST Client? • HTTP Client • Thread
Executer • JSON Deserializer • Integration with RxJava
Retrofit
Retrofit • A type-safe HTTP client for Android and Java
• http://square.github.io/retrofit/ • by Square
Install // Retrofit compile "com.squareup.retrofit2:retrofit:${retrofitVersion}" compile "com.squareup.retrofit2:adapter-rxjava2:${retrofitVersion}" compile "com.squareup.retrofit2:converter-gson:${retrofitVersion}" //
RxJava compile 'io.reactivex.rxjava2:rxandroid:2.0.1' compile "io.reactivex.rxjava2:rxjava:2.1.1"
Retrofit public interface GitHubService { @GET("users/{user}/repos") Call<List<Repo>> listRepos(@Path("user") String user);
}
Retrofit Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.github.com/") .build(); GitHubService service
= retrofit.create(GitHubService.class);
Retrofit GitHubService service = retrofit.create(GitHubService.class); Call<List<Repo>> repos = service.listRepos("srym"); //
synchronous call Response<List<Repo>> response = repos.execute(); // asynchronous call repos.enqueue( /* callback here */ );
Integration with RxJava Retrofit retrofit = new Retrofit.Builder() .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create(gson))
.baseUrl("https://api.github.com/") .build();
Change Return Type public interface GitHubService { @GET("users/{user}/repos") Single<List<Repo>> listRepos(@Path("user")
String user); }
Subscribe Single<List<Repo>> repos = service.listRepos("srym") repos .subscribe( list -> doSomethingToList(list),
throwable -> Timber.d(throwable.getMessage(), throwable), () -> Timber.d("complete") );
Link • RxJava+RetrofitͰAPI௨৴पΓΛ࣮͢Δ͏͑ Ͱ࠷ݶͷࣝΛ30Ͱ٧ΊࠐΉ • http://qiita.com/FumihikoSHIROYAMA/ items/201536d9b45ef21b6bc7
Link • RetrofitΛͬͨOAuth࠶ೝূΞϓϩʔν • http://qiita.com/FumihikoSHIROYAMA/ items/ac1beaeaa9b4baaed939
Link • RetrofitΛͬͨAPIݺͼग़͠ͰϦΧόϦՄೳ ͳHTTPΤϥʔΛͲ͏ѻ͏͔ • http://qiita.com/FumihikoSHIROYAMA/ items/65d52aea1a9f324d347e
What's Good about Retrofit + Rx • Easy to define
• Easy to compose • Easy to test
Test • MockWebServer • TestSubscriber
MockWebServer • A scriptable web server for testing HTTP clients
• https://github.com/square/okhttp/tree/ master/mockwebserver
MockWebServer private final MockWebServer mockWebServer = new MockWebServer();
MockWebServer Dispatcher dispatcher = new Dispatcher() { @Override public MockResponse
dispatch(RecordedRequest request) throws InterruptedException { return new MockResponse().setResponseCode(404); } }; mockWebServer.setDispatcher(dispatcher); mockWebServer.start();
MockWebServer @Override public MockResponse dispatch(RecordedRequest request) { if (request ==
null || request.getPath() == null) { return new MockResponse().setResponseCode(400); } if (request.getPath().matches("/users/.+/repos")) { return new MockResponse().setBody( readJsonFromResources("users_repos.json") ).setResponseCode(200); } return new MockResponse().setResponseCode(404); }
MockWebServer Retrofit retrofit = new Retrofit.Builder() .baseUrl(mockWebServer.url("")) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .build();
GitHubService gitHubService = retrofit.create(GitHubService.class);
TestSubscriber • A TestSubscriber is a variety of Subscriber that
you can use for unit testing, to perform assertions, inspect received events, or wrap a mocked Subscriber. • http://reactivex.io/RxJava/javadoc/rx/ observers/TestSubscriber.html
TestSubscriber restGitHubDataSource .listRepos("srym") .test();
TestSubscriber List<Repo> repos = restGitHubDataSource.listRepos("srym") .test() .await() .assertNoErrors() .assertComplete() .values()
.get(0); assertThat(repos).isNotNull();
TestSubscriber • https://github.com/srym/Architecture • https://github.com/srym/Architecture/blob/ master/app/src/test/java/us/shiroyama/ android/architecture/infrastructure/ repository/datasource/remote/ RestGitHubDataSourceTest.java
Easy to compose • Rx's Observable is easily & flexibly
combined • Avoid callback hells
Easy to compose public class GitHubInfraRepository implements GitHubRepository { private
final RemoteGitHubDataSource remoteDataSource; private final RepoMapper mapper; @Inject public GitHubInfraRepository(RemoteGitHubDataSource remoteDataSource, RepoMapper mapper) { this.remoteDataSource = remoteDataSource; this.mapper = mapper; } @Override public Single<List<RepoModel>> listRepos(@NonNull String user) { return remoteDataSource .listRepos(user) .map(mapper::convert); } }
Easy to compose private final RemoteGitHubDataSource remoteDataSource; private final LocalGitHubDataSource
localGitHubDataSource; private final RepoMapper mapper; @Inject public GitHubInfraRepository(RemoteGitHubDataSource remoteDataSource, LocalGitHubDataSource localGitHubDataSource, RepoMapper mapper) { this.remoteDataSource = remoteDataSource; this.localGitHubDataSource = localGitHubDataSource; this.mapper = mapper; }
Easy to compose @Override public Single<List<RepoModel>> listRepos(@NonNull String user) {
return remoteDataSource .listRepos(user) .map(mapper::convert);
Easy to compose public Single<List<RepoModel>> listRepos(@NonNull String user) { return
localGitHubDataSource .listRepos(user) .onErrorResumeNext( remoteDataSource .listRepos(user) .retry(DEFAULT_RETRY) .doOnSuccess(localGitHubDataSource::save) ) .map(mapper::convert);
Android Clean Architecture • android10/Android-CleanArchitecture • https://github.com/android10/Android- CleanArchitecture • srym/Architecture
• https://github.com/srym/Architecture
None