I'm developing an Android app using Clean Architecture and I'm migrating it to RxJava 2.x. I have to make some network requests to a soap service, so I defined the api interface in the domain module:
public interface SiginterApi {
Observable<User> login(String user, String password);
...
Observable<List<Campaign>> getCampaigns(List<Long> campaignIds);
}
I've read that a network request should be made with "Flowable
", because of the backpressure management since it's a 'cold observable'. On the other hand, I know the result of the request will be success (with the response) or error, so I don't know if I should use Flowable
or Single
or even Observable
.
Furthermore, I have a database accesses like this:
public interface UserRepository extends Repository {
Observable<Void> saveUser(String username, String hashedPassword, boolean logged, User user);
...
Observable<User> findUser(String username, String hashedPassword);
}
I don't know if I should use Completable
/Flowable
/Observable
in saveUser
method and Single
/Flowable
/Observable
in findUser
method.
Backpressure is what you get when a source Observable
is emitting items faster than a Subscriber
can consume them. It's most often a concern with hot observables, not cold ones like your network requests.
I think you should use Completable
instead of Observable<Void>
in your saveUser
method, and use Single
for all places where you follow a request/response or input/output pattern. Observable
should be used when you actually want a continuous stream of events.
Backpressure occurs when an Observable
is emitting items more rapidly than an operator or subscriber can consume them.
Knowing that, Backpressure is not an issue in your case as your Observable
will emit only one item so Flowable
is not a good candidate.
So the real question is whether to use Completable
or Observable
for saveUser
and Single
or Observable
for findUser
and here as only one result is expected (success or failure) for the sake of simplicity and clarity of your API, you should definitively use Completable
/Single
otherwise it will be hard to understand that only one value will be emitted which could be misleading to your API users.
Cardinality is one way of understanding the differences between Completable, Maybe and Single:
- A
Maybe<T>
is just an Observable with cardinality 0 or 1 i.e. it represents a result which can either be present or not. - A
Single<T>
is an Observable that always returns a result i.e. a cardinality of 1. - A
Completable
can be interpreted sort of as aObservable<Void>
i.e. a cardinality of 0.
So in your case you can change the signature of the repository in this way:
Completable saveUser(...);
Single<User> findUser(...);
(I didn't mention Flowable
s which are like Observable
s with backpressure).
As I understand, you should use Single: when you are pretty sure that you are going to get an item, otherwise you would get an error. Eg: GET - card/:id
Maybe: is the correct solution if you are no so sure if you will get an item. Eg: GET - card?license-plate=xvar3
Completable: when you only want to know if the action was made. Eg: PUT or DETELE
Observable: when the quantity of items is not so large.
Flowable: when you don't konw the quantity of items that you will get.
Hmm...
I think the question isn't trivial one while, you have face more complex situation.
Eg. Save user (REST) > Save user (SQLlite)
You may want to chain Rx streams into one.
So either you declare
1.
Flowable<Response<Void>> saveUser(String username, String hashedPassword, boolean logged, User user);
and then use some of: flatMap, contactMap, switchMap
2.
... or I think may be more preferable to not confuse class responsibility (you may use the same code in many places)
Single<Response<Void>> saveUser(String username, String hashedPassword, boolean logged, User user);
RestService.saveUser(...)
.toFlowable() // Transform into Flowable
.switchMap{ saveToDB() }
.subscribeBy{ ... }
.addTo( yourDisposable )
3.
By the way I suggest to not use Completable in case if you want to have nice error handling. You may easily wrap Retrofit.Response<Body>
in Single
or Flowable
to take advantage of the code response from server
来源:https://stackoverflow.com/questions/42525623/rxjava-2-x-should-i-use-flowable-or-single-completable