Melakukan network request ke suatu API sudah menjadi hal yang umum pada aplikasi android. Aktivitas ini digunakan untuk mengakses data yang tersedia untuk selanjutnya diolah dan ditampilkan pada UI aplikasi. Namun, bagaimana jika parameter yang kita butuhkan untuk melakukan request, bergantung pada hasil request yang lain?
Studi Kasus
Kita ingin mengakses data berupa daftar harga produk dari suatu toko, tapi untuk melakukan request tersebut, kita memerlukan parameter ID dari toko tersebut. Disini kita ingin menampilkan toko lengkap dengan daftar harga produknya.
Chain Request
Dari studi kasus tersebut, kita akan melakukan request untuk mengambil ID toko, dan gunakan data tersebut sebagai parameter untuk melakukan request daftar harga produk.
Disini saya menggunakan library retrofit sebagai REST client dan Gson sebagai converternya.
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
Untuk melakukan chain request, saya menggunakan library RxAndroid. Jangan lupa menambahkan adapternya untuk digunakan pada retrofit.
//rx
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
compile 'io.reactivex.rxjava2:rxjava:2.1.0'
//rx adapter untuk retrofit
compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
Buat instance
retrofit menggunakan adapter RxJava.
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(YOUR_BASE_URL)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
Berikut Interface
retrofit yang digunakan untuk menyimpan endpoint API. Saya menggunakan Single
, yaitu semacam Observable
yang hanya menerima sebuah value.
@GET("toko")
Single<Toko> getToko(YOUR_PARAM_HERE);
@GET("harga")
Single<HargaProduk> getHarga(@Query("id") long id);
Selanjutnya kita lakukan chain request menggunakan operator FlatMap
. Operator FlatMap
membuat sebuah Observable
dengan menerapkan fungsi yang kita tentukan untuk setiap item yang dikirim oleh Observable
lainnya. Untuk lebih jelasnya bisa dilihat disini.
Single<Toko> getTokoID = getRestClient().getToko(YOUR_PARAM_HERE);
Single<HargaProduk> dataHargaProduk = getTokoID.flatMap(new Function<Toko>, SingleSource<? extends HargaProduk>>() {
@Override
public SingleSource<? extends HargaProduk> apply(@NonNull Toko toko) throws Exception {
return getRestClient().getHarga(toko.getID());
}
});
Pada contoh diatas, kita melakukan request pertama untuk mendapatkan data toko, kemudian dari data toko yang sudah didapat kita menggunakan ID toko tersebut untuk melakukan request kedua untuk mendapatkan data harga produk.
Langkah terakhir adalah melakukan subscribe
dataHargaProduk.
dataHargaProduk.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new DisposableSingleObserver<HargaProduk>() {
@Override
public void onSuccess(@NonNull HargaProduk harga) {
//olah data
}
@Override
public void onError(@NonNull Throwable e) {
//handle error
}
});
Referensi
- http://reactivex.io/documentation/operators/flatmap.html
- http://reactivex.io/documentation/single.html
- https://square.github.io/retrofit/