RxJava2 / Retrofit2 - call to zero for 204 PUT and DELETE requests

So, I work with an API that is well defined and designed to not return the payload body in DELETE and PUT operations.

This was acceptable in Rx 0.X and Rx 1.x. Now I am upgrading to Rx 2 and have an existential crisis with how I should handle null values. Content length and body, of course, have a null value:

 java.lang.NullPointerException: Null is not a valid element at io.reactivex.internal.queue.SpscLinkedArrayQueue.offer(SpscLinkedArrayQueue.java:68) at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.onNext(ObservableObserveOn.java:116) at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeOnObserver.onNext(ObservableSubscribeOn.java:63) 

in doOnNext.

I have seen that many people offer Optional<> , but I need to support Java7 as well as reasons for using it. I tried to return, but I could not get it to work. I also do not want to inflate and import the Guava library for their version.

I also noticed that flatMap can also help me deal with this without matching the map, and I read about the differences.

Currently, I have a very rude, OkHttp3 interceptor that will check the status, check if the payload is empty, and add dummy content that just makes mistakes.

I also tried to add a factory converter.

Can anyone suggest suggestions and guide me on the right track? Undoubtedly, the API may change, but 204 should not have a payload by virtue of its definition as an HTTP status code.

Relevant Dependencies

 compile('com.squareup.retrofit2:retrofit:2.1.0') { exclude module: 'okhttp' } compile 'com.squareup.retrofit2:converter-gson:2.1.0' compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0' compile 'com.squareup.okhttp3:okhttp:3.5.0' compile 'com.squareup.okhttp3:logging-interceptor:3.5.0' compile 'io.reactivex.rxjava2:rxjava:2.0.5' compile 'io.reactivex.rxjava2:rxandroid:2.0.1' compile 'com.trello.rxlifecycle2:rxlifecycle:2.0.1' compile 'com.trello.rxlifecycle2:rxlifecycle-components:2.0.1' 
+6
source share
2 answers

You need to declare your request method in Retrofit as:

 @DELETE(...) Call<Void> deleteFile(...args); 

In RxJava, your Observable should be introduced:

 @DELETE(...) Observable<Response<Void>> deleteFile(...args); 

In onNext() or doOnNext() you usually get a Response if the request is successful.

If Void does not send the response body to the converter for further deserialization. All empty Call answer should be printed as Void .

+15
source

Since you have RxJava2 and retrofit 2, you can use a more readable way of describing what you really want from the endpoint using Completable .

Completable by design only returns onComplete() and onError(Exception) , so you know what happens when you see it (you only need execution, not the return value), and don’t be surprised what will be in Response<Void> .

So your final call should look like this:

 @DELETE(...) Completable deleteFile(...args); 

Other types are supported; see Retrofit 2 RxJava 2 Adapter page. Single is the one that stands out in terms of api calls.

+5
source

Source: https://habr.com/ru/post/1014520/


All Articles