14

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.

xiaoyaoworm
  • 1,052
  • 4
  • 13
  • 32
  • What import are you using for the DELETE annotation? Confused why the request is parsing it as a GET.... – Lucas Crawford Mar 28 '16 at 01:42
  • @Lucas Very confused now, `import retrofit2.http.DELETE; import retrofit2.http.GET; import retrofit2.http.POST; import retrofit2.http.PUT; import retrofit2.http.Path;` Because when I implement PUT feature but same url, `@PUT("books/{id}") Call updateBook(@Path("id") int bookId , @Body Book book);` I get the same problem, response request method is "GET" – xiaoyaoworm Mar 28 '16 at 02:52
  • For the following question, I create a new question: http://stackoverflow.com/questions/36255825/retrofit-2-0-delete-put-are-not-working – xiaoyaoworm Mar 28 '16 at 04:07

1 Answers1

18

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 :)

Lucas Crawford
  • 3,078
  • 2
  • 14
  • 25
  • Thank you @Lucas. This works!!!!! Before seeing your answer, I think I gave a try on ResponseBody but get failure. Not sure which part I made wrong. Yes, you are right, I think I should put it into AsyncTask otherwise if fetching too many data it will block my UI. RxJava, not sure what it is this but I will check it. Thanks a lot!!! – xiaoyaoworm Mar 27 '16 at 18:53
  • It uses reactive programming to handle networking requests such as you are doing + some functional programming paradigms that makes code cleaner. RxJava makes networking in java much easier for complicated tasks, I'm still learning it myself but a lot of companies are starting to use it and make the swtich – Lucas Crawford Mar 27 '16 at 18:56
  • The program has no problem with your suggestion but I do have another problem. Because I am doing delete work, if calling like this way, I will get response.code() = 200, and the book is not deleted. I give a try on Advanced Rest Cilent, when delete successfully, the response code shown on extension is 204. Do you have some idea on this? RxJava sounds interesting, I should take a look to learn it. Thanks for your suggestion. – xiaoyaoworm Mar 27 '16 at 19:08
  • Yeah, @Lucas totally agree with you, Void makes sense because I don't care anything except response code. – xiaoyaoworm Mar 27 '16 at 19:10
  • https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html Response code 204 means there was success but no entity is included as a body (more reason to use Callback). The link I provided says: "The server has fulfilled the request but does not need to return an entity-body, and might want to return updated metainformation. The response MAY include new or updated metainformation in the form of entity-headers, which if present SHOULD be associated with the requested variant.". So when you see response code 204, that means you successfully deleted. – Lucas Crawford Mar 27 '16 at 19:17
  • yep, you are right. With the code you provided, I can only get 200 rather than 204, after I get 200, I list all the books finding the one I deleted is still there. My problem is why I cannot get 204(this should be delete successfully). Here is the code I follow what you suggested: ` @DELETE("books/{id}") Call deleteBook(@Path("id") int bookId);` `deleteBookCall.enqueue(new Callback() { @Override public void onResponse(Call call, Response response) { if (response.isSuccessful()) {}` – xiaoyaoworm Mar 27 '16 at 19:23
  • Interesting. What List are you checking, a localized one (where the delete wouldn't have removed it) or re-fetching from your database? – Lucas Crawford Mar 27 '16 at 19:29
  • This is what I did, it will fetch all the books on the server, @GET("books") Call> listBooks(); I am playing this on Advanced Rest Client Chrome extension also. From there I can delete successfully and getting 204. – xiaoyaoworm Mar 27 '16 at 19:32
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/107484/discussion-between-xiaoyaoworm-and-lucas-crawford). – xiaoyaoworm Mar 27 '16 at 19:51
  • I find where I make mistakes. http://stackoverflow.com/a/36379787/2011900 I really appreciate with your help!!!! Thanks!!! – xiaoyaoworm Apr 02 '16 at 23:34