5

I have an API that displays Supplier Products

Our UI will allow the user to select various filter criteria and use that to delete a number of products at once.

The problem is that it takes too long do do a few thousand individual HTTP delete requests:

DELETE /api/supplier/6/products/5
DELETE /api/supplier/6/products/7
DELETE /api/supplier/6/products/8
DELETE /api/supplier/6/products/10
...

The intention is to make one HTTP call to delete a bunch of supplier products at once. I can pass a body to the delete so that it contains a list of all the ID's that we would like to delete:

DELETE /api/supplier/6/products
Body:
{
  "DeleteIds": "[5,7,8,10]"
}

This worked well until we put it behind our production proxy firewall which stripped the body from the DELETE request.

I have had a look at the HTTP Spec RFC 2616 Fielding, et al. and it doesn't explicity state that I shouldn't use a body in a DELETE request and further reading has shown that there isn't anything wrong with sending a body with a DELETE request.

I have control over our proxy server and have been able to allow the body to be passed through for all requests, but I worry that this may not be best practise. We could have thousands of Id's that we pass through and I don't want to us headers or URL parameters as we could run up against length restrictions.

So my question is: What would be the correct way to do a Delete for multiple products using the body of a request? Not just an opinion, but is there actual documented evidence out there for as to why I should not use the body of a HTTP DELETE?

Should I continue with

DELETE /api/supplier/6/products (Using a body)

or should not use DELETE with a body and instead do a POST to something like

POST /api/supplier/6/products/deletemultiple

Edit: There is some good debate in this question: Restful way for deleting a bunch of items It doesn't address my question about using the body of a DELETE request for a custom delete action, but there is some good debate on different ways that a batch delete can happen.

Community
  • 1
  • 1
ShaunP
  • 453
  • 1
  • 5
  • 20
  • I would go for your first option for sure: DELETE /api/supplier/6/products – TBD Jan 20 '17 at 14:59
  • I agree, use the DELETE rather than POST – bolt19 Jan 20 '17 at 15:00
  • I want to understand if we can POST the ID list. That does work but may not be the correct approach? – Souvik Ghosh Jan 20 '17 at 15:01
  • This question should be closed as it is purely opinion-based. – Mark C. Jan 20 '17 at 15:17
  • FWIW, stop looking at RFC 2616. It's obsolete. Use RFC 7231 instead. And no, that doesn't affect the answer. – Julian Reschke Jan 20 '17 at 15:21
  • RFC 2616 shouldn't be referenced any more. It's been replaced by a number of RFCs in the 72xx range. I think you'd want to consult [7231](https://tools.ietf.org/html/rfc7231#section-4.3.5): "A payload within a DELETE request message has no defined semantics" – Damien_The_Unbeliever Jan 20 '17 at 15:21
  • So [RFC 7231](https://tools.ietf.org/html/rfc7231#section-4.3.5) states: A payload within a DELETE request message has no defined semantics; sending a payload body on a DELETE request might cause some existing implementations to reject the request. – ShaunP Jan 20 '17 at 15:24
  • Possible duplicate of [Restful way for deleting a bunch of items](http://stackoverflow.com/questions/2421595/restful-way-for-deleting-a-bunch-of-items) – sashoalm Jan 20 '17 at 15:32
  • You should just delete this question if no answers have helped you thus far. – Mark C. Jan 23 '17 at 14:17

2 Answers2

1

I've done both, and when I want to pass several items to a delete action I use a POST and just have an int[] as the parameter, but I make sure that the URL I am calling is very explicit since I'm using configuration over convention: i.e:

/api/products/DeleteAllById

If I am deleting individual items, then I will use DELETE.

Mark C.
  • 5,789
  • 4
  • 31
  • 60
  • That makes sense though – Souvik Ghosh Jan 20 '17 at 15:04
  • Yep, we delete individual items by a simple DELETE /api/products/5 I just am not sure whether to DELETE /api/products (with a body) or POST /api/product/deleteallbyid (with a body) – ShaunP Jan 20 '17 at 15:04
  • 1
    My vote would be the `POST` if you are already implementing a `DELETE`. `POST` allows a bigger request, I believe. – Mark C. Jan 20 '17 at 15:05
  • If this is a bad approach, someone please enlighten me. – Mark C. Jan 20 '17 at 15:11
  • It is just not straightforward in common concept. Well, actually, that means concept is need to be upgraded to multi-changing one (CRUD but on sets) =) – eocron Jan 20 '17 at 15:14
  • @eocron06 OP has not given us his RouteConfig or anything, so it is difficult to provide an accurate solution. Also, the question is purely opinion-based – Mark C. Jan 20 '17 at 15:16
  • @Mark C - I've been doing some extra reading and found https://cloud.google.com/apis/design/custom_methods Looks like google will implement your method of a POST to /api.product:deleteallbyid endpoint. Nice one! – ShaunP May 24 '17 at 13:34
  • @ShaunP Thanks - it's just very easy to implement and to me it just makes sense to do it this way. – Mark C. May 24 '17 at 13:35
-1

First of all, you should put your ids inside your request URL for this to even work.

Second, batch your request on client side (split it into chunks of fixed id count). Maximum lenght of URL is limited by 2000, so, I suggest to limit your batch id count by 100 or something like this. This way you get maximum performance and minimal network load.

Well, if you want to hack this out instead of using concept of REST and pretty common technique of batching, just use POST and don't bother about batching. Actually, it has some sense in it, because HTML don't even support DELETE =/ It is just faked with some frameworks (Ruby on Rails, Javascript, AJAX, etc)

eocron
  • 5,589
  • 16
  • 40