How can we chain the APIs and get result from one of the APIs?
Today let’s talk about a scenario: we’d like to implement a new feature to publish a new post on our app, and we have to follow the flow:
- Make a API1 request to create media ID.
- Get the media upload URL from location header of API1.
- Upload file to that media upload URL.
- Store the media ID to the media.
- Wait for push notification with media ID to confirm that the job on server side for that media is done.
The first API to create media ID and get media upload URL:
The second API to upload media:
Problem to solve?
You need to call two APIs (or more) sequentially and chain together, both the two APIs success, then the publish flow successes, once one of the APIs fail, then the whole flow is considered to be failed. After the both API calls, we have to get the post ID from API1, how can we chain the APIs and get result from the first API?
Here we use RxJava to help us solve this problem, and use Retrofit and Okhttp for API call, let’s convert each API requests into several standalone
Observable: (for clear and convenient, we choose API1, API2, … to represent the first, second… API than the real production name)
1. We define the data class for API response first, this data class to store the response from API1:
2. The two APIs observables:
RxJava.flapMap() to chain the API1 -> API2:
And its subscriber:
This is the common way to chain two API calls by using
flatMap() You can find that the return type in subscriber is the same type from the last observable, i.e.
okhttp3.Response, it doesn’t include the media ID from API1, however, we need the media ID from API1 after API2, what can we do to achieve that then?
We can simple use
map() operator to apply a pair function to map the media ID from API1 and API2 together:
And its new subscriber can get the pair of media ID and
We can use
zip() operator to combine the media ID from API1 along with API2, that is
api1.flatmap -> zip(api1Result, api2) , the original implementation above is
api1.flatmap -> api2:
We also can use
cache() to help alternatively.
The operator order is
There are still some variants for this use case, you can find it out by yourself, happy coding!