Multiple API calls with retrofit and RXJava 2

I have a question in order to understand better a RX Java solution with retrofit in Android, the problem is the following: I have an application that has an offline mode with a local database, while I'm working with the app, process in there are recorded into database and then send it to the backend to be saved. In this case I have some process that change status in a order, for example I have an action who change arriving status of a job, another who change a Job started status, and 4 more actions that change statuses in the a process. this statuses are saved into different local database tables and have to make multiple API call to change that statuses 1 for each status. explaning this, I have a screen in my app that group all process statuses for every JOB that are pending to send to backend, so in this case are grouped by ID of Job, so I would like to press a button in my app screen and send all of this statuses calling every API and get a result when finish with all that calls in order to put a loading progress and remove it when finish, clear local database with all statuses that where send it well, and finish activity. I know that RX Java has the ZIP option to call API's and wait for the result, but in this case I don't know if it's possible because I have to call every API for every same status of all jobs, example: I have JOB 1, 2, 3 and 4.

  1. Job 1 - Has status 1, status 2, status 3.
  2. Job 2 - Has status 1, status 2.
  3. job 3 - Has status 1, status 2, status 3, status 4.
  4. Job 4 - Has status 1.

Every status has 1 API to be cosumed. so I need to make a process who call every API gruped by status, call all API's and get response of every call in order to delete statuses for internal table and when all finish put ProgressBar = Hide and refresh a recycler view. I woul like to run all in parallel and get result when all calls finish. I don't know if i'm clear with my problem but if not, I coud explain it with more detail or answer your questions. Please I would happy with your help.

Upvotes: 1

Views: 5791

Answers (1)

canihazurcode
canihazurcode

Reputation: 262

Based on the answer posted here: How can I make this rxjava zip to run in parallel? I suggest zipping observables in parallel.

Suppose you build your calls to API like that:

public class Api {
    @POST("api 1 url")
    Observable<ResponseObject> postStatus1(...);

    @POST("api 2 url")
    Observable<ResponseObject> postStatus2(...);
}

You have to prepare your observables to be executed in parallel for selected job:

private Api api;

public List<Observable<ResponseObject>> prepareObservables(Job job) {
    List<Observable<ResponseObject>> list = new ArrayList<>();

    //Get all states for given job
    for(String status : job.getStates()) {
        // check which api method you need to call
        if(status.equals("STATUS1") {
            //subscribtion on a new thread will ensure calls are executed in parallel                
            list.add(api.postStatus1(...).subscribeOn(Schedulers.newThread()))
        }

        ...
    }

    return list;
}

Now zip the observables and execute

public void runObservables(List<Job> pendingJobs) {
    List<Observable<ResponseObject>> allObservables = new ArrayList<>();

    for(Job job : pendingJobs) {
        list.addAll(prepareObservables(job));
    }

    Observable.zip(allObservables, new Function<Object[], Object>() {
        @Override
        public Object apply(Object[] o) throws Exception {
            // you can combine respones from API here
        }).subscribe(new Consumer<Object>() {
            // this block of code executes when all calls to your api were successfull
            // do what you need to, i.e. delete jobs from db
        });
}

Upvotes: 2

Related Questions