NetworkBoundResource: Kotor dan Aneh

 



Saya tau mungkin bagi beberapa orang tidak setuju dengan saya, apalagi mereka yang sangat mengikuti google approach di projek android mereka. Jika anda tak setuju dan memang sedang tidak membuka opini lain soal NetworkBoundResource, silakan tutup tab ini.


Awal Mula

Jujur saja, saya sendiri tidak pernah menggunakan NetworkBoundResource ini. Sebelumnya juga saya belum pernah melihat kodenya seperti apa, hanya pernah mendengar atau melihat sekilas saja di beberapa artikel.

Suatu hari, saya diminta oleh kawan yang sedang mengikuti program bootcamp di salah satu penyedia pembelajaran software yang sangat besar di Indonesia, perusahaan tersebut bekerja sama dengan google dan lain sebagainya, ya, saya rasa anda sudah tau.

Kawan saya ini bertanya, kenapa aplikasinya tidak menampilkan data sesuai keinginannya, lebih spesifik, dia menggunakan NetworkBoundResource dan Paging (jujur saja, soal android paging ini menurut saya juga sedikit nasty, hahaha). Nggak pake lama, saya minta akses ke github dia, clone projeknya di komputer saya dan membukanya.

Saya menemukan kode NetworkBoundResource di situ, yang perlu waktu cukup lama untuk saya mengerti.



Apa Sebenarnya NetworkBoundResource?

NetworkBoundResource sebenarnya adalah sebuah class yang berfungsi seperti handler untuk menampilkan data dari local storage/database, sekaligus mem-fetch ulang data dari internet. Singkatnya, saat aplikasi dibuka, data yang dimunculkan adalah data yang telah disimpan di cache sebelumnya, lalu data yang terbaru, akan diambil ulang via http request ke API, saat data terbaru sudah didapat, cache juga ikut diperbarui, dan data yang terbaru juga akan diteruskan ke tampilan.

Secara umum, fungsinya memang seperti yang saya jelaskan di atas, namun untuk implementasinya bisa berbeda-beda tergantung pada programmernya. Berikut beberapa implementasi yang saya temukan:

- Coding In Flow

- Android Architecture

- Android Documentation


Kenapa Kotor dan Aneh?

Pertama kali melihat kode NetworkBoundResource yang kawan saya berikan, hal yang paling membuat saya gatal adalah output dari kelas ini adalah sebuah obervable (saya menyebutnya observable ketimbang live data, karena term observable lebih umum, mengingat implementasi dari kelas ini sangat bervariasi) yang menggabungkan data dan ui state. Jadi, singkatnya, kelas ini bisa mengembalikan data, bisa mengembalikan state (seperti isLoading), bisa juga mengembalikan error.

Penggabungan inilah yang menurut saya kotor, karena tidak ada separasi data yang keluar. Semua dimasukkan jadi satu (biasanya, menggunakan MediatorLiveData). Hal yang lebih aneh akan terasa kalau dilihat saat mengconsumenya di UI.


Gambar tersebut diambil dari channel Coding in Flow


Seperti pada gambar di atas yang saya screenshot dari salah satu video milik Coding in Flow di youtube, pada line 31 dia mengobserve live data, untuk menampilkna loading indicator, perlu dilakukan pengecekan dengan keyword "is" untuk mengetahui live data tersebut membawa ui state atau tidak. Hal ini nampak oke saja sepertinya, namun kebanyakan kasus, loading indicator tidak bergantung pada hasil dari satu data saja, jadi menurut saya, lebih baik keduanya dipisah (antara data dan ui state).


Selain itu, seringkali pemanggilan netwrokBoundResource ini dilakukan di repository. Kalau dipikir-pikir lagi, networkBoundResource menjadi lebih superior ketimbang repository (maka networkBoundResource lah yang menjadi repository sebenarnya).


Hal yang benar-benar aneh adalah, contoh ini tertulis di android documentation, meskipun documentation bukanlah sesuatu yang dogmatik, tapi seringkali documentation menjadi acuan pertama dalam mencari solusi.


Saya sempatkan untuk mencari artikel dan pendapat orang lain, apakah hanya saya saja yang mengeluhkan soal ini? Ternyata saya tidak sendirian, Vasiliy Zulkanov juga berkomentar hal yang sama di artikelnya. Engineer-engineer lain juga berkomentar soal ini seperti Gabor Varadi dan Mitch Tabian (Coding with Mitch).




Lihat obrolan mereka di tweet ini.


Cara Yang Lebih Mudah?

Untuk saya sendiri lebih suka approach yang diberikan oleh Adam McNeilly di tweet ini.



Kode di atas memiliki kelemahan yakni network request tidak akan pernah dieksekusi jika terdapat data di local database. Dalam beberapa kasus, kita tidak peduli, baik data ada ataupun tidak ada, network request harus tetap dipanggil untuk mengambil data terbaru dari server.

Untuk mengatasi hal ini, saran saya pribadi adalah menggunakan kotlin flow, alih-alih mengembalikan data dengan keyword return, kita menggantinya dengan keyword emit. Berbeda dengan return, emit akan mengembalikan value dan juga meneruskan kodenya, sedangkan return akan berhenti. Jangan langsung diimplementasikan dengan gambar di atas karena akan lumayan jauh berbeda implementasinya, saran saya anda membaca soal kotlin flow terlebih dahulu. Untuk java, nampaknya RxJava bisa digunakan sebagai pengganti kotlin flow.


Talk Is Cheap, Show Me The Code!

Implementasi yang saya lakukan kurang lebih seperti gambar-gambar di bawah ini. Intinya, dalam repository, saya passing dua parameter, yakni remote source dan local source (dao). Untuk lebih jelasnya, bisa dilihat di repository github ini.






Atau bisa menonton video yang saya buat di youtube playlist ini:



Penutup

Saya tidak bermaksud untuk menjustifikasi benar dan salah, ini hanya pendapat pribadi yang mungkin orang lain juga merasa kesulitan menerapkan networkBoundResource ini dan mencari alternatifnya.

Post a Comment

0 Comments