So, I am working with an API that is clearly defined and is designed to not return a payload body on DELETE
and PUT
operations.
This was acceptable in Rx 0.X and Rx 1.x. Now I'm updating to Rx 2 and having an existential crisis with how I should handle the null values. The content-length and body are of course null causing:
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 the doOnNext.
I've seen many people suggest Optional<>
but I need to support Java7 as well for use case reasons. I attempted back-porting but I couldn't quite get it to work. I also don't want to bloat and import the Guava library for their version.
I also noticed flatMap may also help me handle this opposed to map and I'm reading up on the differences.
Currently I have a very crude, OkHttp3 Interceptor that will check the status, check if the payload is empty, and add dummy content which just feels so wrong.
I've also tried to add a convert factory.
Can anyone offer suggestions and guide me on what the proper path is? Sure, the API can change, but 204 isn't supposed to have a payload by virtue of it's definition as an HTTP status code.
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'
You need to declare your request method in Retrofit
like:
@DELETE(...)
Call<Void> deleteFile(...args);
In RxJava your Observable
has to be typed:
@DELETE(...)
Observable<Response<Void>> deleteFile(...args);
In onNext()
or doOnNext()
you will receive the Response
normally, if the request is successful.
Having Void
will not send the response body to the converter for further deserialization. All empty-response Call
s should be typed as Void
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With