Slide 1

Slide 1 text

͸΍͍ɾ΍͍͢ɾ͏·͍ʂ
 ελʔτΞοϓͰ΋࢖͑Δ Retrofit + RxJava ͰॠؒAPIΫο ΩϯάϨγϐ @fushiroyama

Slide 2

Slide 2 text

About Me • Fumihiko Shiroyama • Android App Developer • https://github.com/srym

Slide 3

Slide 3 text

How to implement REST Client? • HTTP Client • Thread Executer • JSON Deserializer • Integration with RxJava

Slide 4

Slide 4 text

Retrofit

Slide 5

Slide 5 text

Retrofit • A type-safe HTTP client for Android and Java • http://square.github.io/retrofit/ • by Square

Slide 6

Slide 6 text

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"

Slide 7

Slide 7 text

Retrofit public interface GitHubService { @GET("users/{user}/repos") Call> listRepos(@Path("user") String user); }

Slide 8

Slide 8 text

Retrofit Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.github.com/") .build(); GitHubService service = retrofit.create(GitHubService.class);

Slide 9

Slide 9 text

Retrofit GitHubService service = retrofit.create(GitHubService.class); Call> repos = service.listRepos("srym"); // synchronous call Response> response = repos.execute(); // asynchronous call repos.enqueue( /* callback here */ );

Slide 10

Slide 10 text

Integration with RxJava Retrofit retrofit = new Retrofit.Builder() .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create(gson)) .baseUrl("https://api.github.com/") .build();

Slide 11

Slide 11 text

Change Return Type public interface GitHubService { @GET("users/{user}/repos") Single> listRepos(@Path("user") String user); }

Slide 12

Slide 12 text

Subscribe Single> repos = service.listRepos("srym") repos .subscribe( list -> doSomethingToList(list), throwable -> Timber.d(throwable.getMessage(), throwable), () -> Timber.d("complete") );

Slide 13

Slide 13 text

Link • RxJava+RetrofitͰAPI௨৴पΓΛ࣮૷͢Δ͏͑ Ͱ࠷௿ݶͷ஌ࣝΛ30෼Ͱ٧ΊࠐΉ • http://qiita.com/FumihikoSHIROYAMA/ items/201536d9b45ef21b6bc7

Slide 14

Slide 14 text

Link • RetrofitΛ࢖ͬͨOAuth࠶ೝূΞϓϩʔν • http://qiita.com/FumihikoSHIROYAMA/ items/ac1beaeaa9b4baaed939

Slide 15

Slide 15 text

Link • RetrofitΛ࢖ͬͨAPIݺͼग़͠ͰϦΧόϦՄೳ ͳHTTPΤϥʔΛͲ͏ѻ͏͔໰୊ • http://qiita.com/FumihikoSHIROYAMA/ items/65d52aea1a9f324d347e

Slide 16

Slide 16 text

What's Good about Retrofit + Rx • Easy to define • Easy to compose • Easy to test

Slide 17

Slide 17 text

Test • MockWebServer • TestSubscriber

Slide 18

Slide 18 text

MockWebServer • A scriptable web server for testing HTTP clients • https://github.com/square/okhttp/tree/ master/mockwebserver

Slide 19

Slide 19 text

MockWebServer private final MockWebServer mockWebServer = new MockWebServer();

Slide 20

Slide 20 text

MockWebServer Dispatcher dispatcher = new Dispatcher() { @Override public MockResponse dispatch(RecordedRequest request) throws InterruptedException { return new MockResponse().setResponseCode(404); } }; mockWebServer.setDispatcher(dispatcher); mockWebServer.start();

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

MockWebServer Retrofit retrofit = new Retrofit.Builder() .baseUrl(mockWebServer.url("")) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .build(); GitHubService gitHubService = retrofit.create(GitHubService.class);

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

TestSubscriber restGitHubDataSource .listRepos("srym") .test();

Slide 25

Slide 25 text

TestSubscriber List repos = restGitHubDataSource.listRepos("srym") .test() .await() .assertNoErrors() .assertComplete() .values() .get(0); assertThat(repos).isNotNull();

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

Easy to compose • Rx's Observable is easily & flexibly combined • Avoid callback hells

Slide 28

Slide 28 text

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> listRepos(@NonNull String user) { return remoteDataSource .listRepos(user) .map(mapper::convert); } }

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

Easy to compose @Override public Single> listRepos(@NonNull String user) { return remoteDataSource .listRepos(user) .map(mapper::convert);

Slide 31

Slide 31 text

Easy to compose public Single> listRepos(@NonNull String user) { return localGitHubDataSource .listRepos(user) .onErrorResumeNext( remoteDataSource .listRepos(user) .retry(DEFAULT_RETRY) .doOnSuccess(localGitHubDataSource::save) ) .map(mapper::convert);

Slide 32

Slide 32 text

Android Clean Architecture • android10/Android-CleanArchitecture • https://github.com/android10/Android- CleanArchitecture • srym/Architecture • https://github.com/srym/Architecture

Slide 33

Slide 33 text

No content