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
150
AWS Device FarmとCircleCIでAndroidのUIテストを自動化しよう
srym
1
5.2k
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.9k
I/O 2017 Short Report
srym
0
320
Mock Partially using Dagger
srym
0
670
Other Decks in Technology
See All in Technology
kotlin-lsp を Emacs で使えるようにしてみた / use kotlin-lsp in Emacs
nabeo
0
150
Autonomous Database サービス・アップデート (FY25)
oracle4engineer
PRO
2
770
kubellが挑むBPaaSにおける、人とAIエージェントによるサービス開発の最前線と技術展望
kubell_hr
1
290
成立するElixirの再束縛(再代入)可という選択
kubell_hr
0
250
(非公式) AWS Summit Japan と 海浜幕張 の歩き方 2025年版
coosuke
PRO
1
230
Javalinの紹介
notoh
0
100
TODAY 看世界(?) 是我們在看扣啦!
line_developers_tw
PRO
0
160
宇宙パトロール ルル子から考える LT設計のコツ
masakiokuda
2
100
Workflows から Agents へ ~ 生成 AI アプリの成長過程とアプローチ~
belongadmin
3
150
菸酒生在 LINE Taiwan 的後端雙刀流
line_developers_tw
PRO
0
140
技術職じゃない私がVibe Codingで感じた、AGIが身近になる未来
blueb
0
120
キャディでのApache Iceberg, Trino採用事例 -Apache Iceberg and Trino Usecase in CADDi--
caddi_eng
0
100
Featured
See All Featured
StorybookのUI Testing Handbookを読んだ
zakiyama
30
5.8k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
161
15k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
30
2.1k
jQuery: Nuts, Bolts and Bling
dougneiner
63
7.8k
Documentation Writing (for coders)
carmenintech
71
4.9k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
181
53k
Site-Speed That Sticks
csswizardry
10
630
Why You Should Never Use an ORM
jnunemaker
PRO
56
9.4k
GraphQLとの向き合い方2022年版
quramy
46
14k
Facilitating Awesome Meetings
lara
54
6.4k
Imperfection Machines: The Place of Print at Facebook
scottboms
267
13k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
331
22k
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