94
@DELETE("/job/deletejob")
 Observable<JobDeleteResponseModel> jobDelete( @Body JobDeleteRequestModel model);

am getting this error:

Non-body HTTP method cannot contain @Body or @TypedOutput

Ruli
  • 2,592
  • 12
  • 30
  • 40
sandy
  • 943
  • 1
  • 6
  • 6
  • Try Query instead of Body as Bodies on DELETE requests have no defined semantics. Note that sending a body on a DELETE request might cause some existing implementations to reject the request. – PN10 Jun 21 '16 at 11:02
  • Check this link it might help u https://github.com/square/retrofit/issues/458 – PN10 Jun 21 '16 at 11:08

9 Answers9

250

I've used this official workaround recently:

@HTTP(method = "DELETE", path = "/job/deletejob", hasBody = true)
Observable<JobDeleteResponseModel> jobDelete(@Body JobDeleteRequestModel model);
AndroidEx
  • 15,524
  • 9
  • 54
  • 50
  • 1
    Not working. I have used in below link: https://stackoverflow.com/questions/48539478/custom-http-method-not-working-in-retrofit-2# Can you please help. – Chetak Bhimani Feb 02 '18 at 07:14
  • working fine. i trapped in whole day and going to change my api method from backend ,but you save my day..thanks – Ajay Mistry Jul 03 '20 at 08:47
  • `path` is not mandatory if your first argument to interface method is a url annotated with @Url . More here details here : stackoverflow.com/a/62920127/8956093 – Ramakrishna Joshi Jul 15 '20 at 19:22
22

You need to specify parameters
method, path, hasBody

Kotlin way

@HTTP(method = "DELETE", path = "event/eventRemovePicture", hasBody = true)
fun callDeleteImage(
    @Body body: RequestBody
): Call<RemoveEventPictureResponse>
Aditya Patil
  • 1,287
  • 12
  • 19
14

I had similar error.

In my case I was using @GET in Interface but then I corrected it to @POST method and it worked.

Makarand
  • 983
  • 9
  • 27
12

try this it's work

@HTTP(method = "DELETE", path = "api/v3/delete", hasBody = true)
Call<ResponseBody> RESPONSE_BODY_CALL(@Header("Authorization") String authorization, @Body HashMap<String, List> stringListHashMap);

or check https://github.com/square/retrofit/issues/974

Community
  • 1
  • 1
Shiv Kumar
  • 635
  • 7
  • 13
8

Change

@DELETE("/job/deletejob")
Observable<JobDeleteResponseModel> jobDelete( @Body JobDeleteRequestModel model);

to

@HTTP(method = "DELETE", path = "/job/deletejob", hasBody = true)
Observable<JobDeleteResponseModel> jobDelete( @Body JobDeleteRequestModel model);

The difference is in

@DELETE("/job/deletejob") // For DELETE without body
@HTTP(method = "DELETE", path = "/job/deletejob", hasBody = true) // For DELETE with body
5

Kotlin Code :

path is not required if your first argument to interface method is a url annotated with @Url Example :

@HTTP(method = "DELETE", hasBody = true)
fun deleteStudentFromDatabase(
    @Url url: String,
    @Body payload: StudentModel
 ): Observable<Any>

If first argument to interface method is not a url then use this

    @HTTP(method = "DELETE", path = "{urlPath}", hasBody = true)
    fun deleteStudentFromDatabase(
        @Body payload: StudentModel,
        @Path("urlPath") url: String
     ): Observable<Any>
Ramakrishna Joshi
  • 1,442
  • 17
  • 22
1
@HTTP(method = "DELETE", path = "{urlPath}", hasBody = true)

Also this is working fine. It happens because the request contains a body but we have not defined that yet.

Ruli
  • 2,592
  • 12
  • 30
  • 40
1

Retrofit 2, i have change the below code from this

@DELETE("example/user/{id}/list")
suspend fun deleteUserList(@Path(value = "id", encoded = false)key: Int, @Body request: DeleteUserListRequest): Response<BaseResponse>

to

@HTTP(method = "DELETE", path = "example/user/{id}/list",hasBody = true)
suspend fun deleteUserList(@Path(value = "id", encoded = false)key: Int, @Body request: DeleteUserListRequest): Response<BaseResponse>

Above code is working for me

Navin Kumar
  • 3,393
  • 3
  • 21
  • 46
0

Kotlin with suspend function. By default DELETE method do not supports body. You should explicitly enable it.

@HTTP(
    method = "DELETE",
    path = "path/to/api/{someRoute}/{id}", 
    hasBody = true
)
suspend fun delete(
    @Path("someRoute") someRoute: String,
    @Path("id") id: String,
    @Body body: SomeBodyModel,
): Response<Unit>

Use it something like this

suspend fun delete(model: SomeBodyModel) {
    val response = api.delete(model)
    if (!response.isSuccessful) throw HttpException(response)
}
Nikolay
  • 21
  • 4