Skip to content

Blog


Synchronizing Network Calls With RxJava

July 13, 2018

|
Rohan Garg

Rohan Garg

Wei Lin

Wei Lin

Most Android apps rely on network calls to a set of backend services. As an app grows, so does the complexity of network calls and data operations. Networking libraries like Retrofit and Volley provide all the functionality needed for basic API calls. However, for threading and sequencing of events beyond a single API call, you may end up writing messy, error-prone code. Enter RxJava, an extension of the Observable pattern that abstracts away the complexities of threading and synchronization and integrates seamlessly with Retrofit.

At DoorDash, we’ve experimented with RxJava and found that it has tremendous benefits. In this blog post, we’ll talk about how using RxJava allows us to handle network operations in a reliable, scalable way.

Let’s start off with a basic example in the DoorDash consumer app that makes an asynchronous API call via Retrofit to fetch the list of restaurants at a given location. Using Retrofit’s Callback<T> interface, we perform the request on a background thread and get the response in onResponse on the main thread.

https://gist.github.com/137dbbd8e4a58884c8c96f146ad11974

While this approach works fine for this basic use case, it does not scale much beyond that. Let’s consider a requirement change.

Chaining API Calls

Let’s say the requirement now changes to fetch restaurants based on the user’s default address on login. For this, we have to first make the API call to fetch the user info and then fetch the restaurant list. Using the previous approach, this is what it would look like:

https://gist.github.com/c63033d011bd498317d68378d0753504

Let’s look at the problems in this code:

  • It’s not readable because of multiple nested callbacks
  • It’s not trivial to make the API call aware of lifecycle changes, which can lead to crashes when updating the view
  • The API call to fetch user info is tightly coupled to the call that fetches the restaurant list

Let’s see how RxJava helps us with this problem:

https://gist.github.com/6daffe76b538bea24ee5989f6875ef0d

It addresses the above issues in the following manner:

  • Makes the code clean and readable
  • The fragment can subscribe to the Observable, which makes the API calls on a background thread and emits data on the main thread, as specified with subscribeOn and observeOn. It can unsubscribe from the Observable to stop receiving data from it, as done in onPause
  • Adding API calls to the chain is easy, without much overhead

Making Parallel Requests

Let’s say we want to run an A/B test to display photos for the fetched restaurants. Let’s assume we have an API call that returns a boolean value of the experiment for the current user, where “true” means we should show restaurant photos in the list. Using the same approach from before, we could just use another flatMap operator to first fetch the restaurants and then fetch the experiment value to display the correct experience based on the experiment value. However, ideally we should make the calls in parallel since they are independent of each other and combine their results.

Let’s see how we can do this with the the zipWith operator:

https://gist.github.com/2c59b83b8c777e1fc31c4d01f27a09ea

RxJava comes with a powerful set of operators that can be used to compose sequences together. For this use case, we make the two API calls in parallel and combine their results using the zipWith operator before emitting the final result.

Conclusion

Hopefully these examples showed you that RxJava can help you easily adapt to the changing needs of your app via it’s APIs and operators. Our Android apps have benefited from using RxJava for solving problems such as combining data streams, search-as-you-type, and polling. Let us know if you have additional thoughts on how RxJava can help with your applications or come join the team.

About the Authors

  • Rohan Garg

    Rohan Garg interned for DoorDash in the summer of 2024.

  • Wei Lin

Related Jobs

Location
Toronto, ON
Department
Engineering
Location
San Francisco, CA; Sunnyvale, CA
Department
Engineering
Location
San Francisco, CA; Mountain View, CA; New York, NY; Seattle, WA
Department
Engineering
Location
San Francisco, CA; Sunnyvale, CA; Seattle, WA
Department
Engineering
Location
San Francisco, CA; Sunnyvale, CA; Seattle, WA
Department
Engineering