Retrofit 2.0 how to delete?

xiaoyaoworm picture xiaoyaoworm · Mar 27, 2016 · Viewed 16k times · Source

I am using retrofit 2.0 and I am implementing a delete feature in my Android app, however, I cannot make it successfully, can someone give me a suggestion?

I tried both:

@DELETE("books/{id}") void deleteBook(@Path("id") int itemId);

@DELETE("books/{id}") void deleteBook(@Path("id") int bookId, Callback<Response> callback);

I get error java.lang.IllegalArgumentException: Service methods cannot return void. for method LibraryService.deleteBook.

I also gave a try on this:

Response deleteBook(@Path("id") int bookId);

Call<Response> deleteBook(@Path("id") int bookId);

no matter I use okhttp3.Response or retrofit2.Response, I will get the error: '*.Response' is not a valid response body type. Did you mean ResponseBody?

Can someone give me a successful delete example? I googled online but cannot find enough information. Thanks a lot.

Answer

Lucas Crawford picture Lucas Crawford · Mar 27, 2016

Do it this way as you noted last:

Call<ResponseBody> deleteBook(@Path("id") int bookId);

Make sure you make the call off the UI-thread via AsyncTask or some other threading mechanism. Not sure if you've used RxJava + Retrofit 2 before, but it is nice.

The ResponseBody object will return the results from the call. It is what I use for some REST API requests that don't return an entity object, and all I care about is looking at the response code.

Call<ResponseBody> deleteRequest = mService.deleteBook(123);
deleteRequest.enqueue(new Callback<ResponseBody>() {
    @Override
    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
        // use response.code, response.headers, etc.
    }

    @Override
    public void onFailure(Call<ResponseBody> call, Throwable t) {
        // handle failure
    }
});

Or, Jake Wharton suggests

Use Void which not only has better semantics but is (slightly) more efficient in the empty case and vastly more efficient in a non-empty case (when you just don't care about body).

So you have:

Call<Void> deleteBook(@Path("id") int bookId);

Usage:

deleteRequest.enqueue(new Callback<Void>() {
    @Override
    public void onResponse(Call<Void> call, Response<Void> response) {
        // use response.code, response.headers, etc.
    }

    @Override
    public void onFailure(Call<Void> call, Throwable t) {
        // handle failure
    }
});

This is better if all you care about is the response code and no body to the response

EDIT 2: Left out the proper Callback definition. Fixed :)