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/