7

I send a delete request to server as like:

@RequestMapping(value = "/user/{userId}", method = RequestMethod.DELETE)

for a single user delete. However what to do when multiple users wants to be deleted? I want to obey REST architecture but I want to see the another ways from sending multiple delete requests?

PS: Is this a suitable way:

@RequestMapping(value = "/user", method = RequestMethod.DELETE, headers = "Accept=application/json")
    public void deleteUser(HttpServletResponse response, @RequestBody String users) throws IOException {
        ...
}
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
kamaci
  • 72,915
  • 69
  • 228
  • 366
  • Did you mean `RequestMethod.DELETE`? – Tomasz Nurkiewicz Sep 22 '11 at 07:38
  • 1
    @kamaci: A DELETE normally has no body, so you can't send the user ids along with it. DELETE normally deletes the whole resources (and all subresources). I wrote an answer which uses POST instead of DELETE but is similar to you edit. – ZeissS Sep 22 '11 at 07:55

4 Answers4

6

since rest is resource oriented arch.

try design a higher level domain object which represents 'multiple users' resource ,

do delete on that object.

maybe

@RequestMapping(value = "/users/expired", method = RequestMethod.Delete)

the great book 'restful web services cookbook' by Subbu Allamaraju , oreilly , talk about this topic:

  • chapter 11.10, how to batch process similar resources;
  • chapter 11.11, how to trigger batch operation;
  • chapter 11.12, when to use post to merge multiple request ;
  • chapter 11.13, how to support batch request
swanliu
  • 781
  • 3
  • 8
  • It doesn't have to be a domain object, just an additional resource to represent the set of objects. – Darrel Miller Sep 22 '11 at 11:09
  • Yes, this is the best option. Another one would be HTTP pipelining but that isn't widely enough implemented (yet). PS: Do sth for your accept ate and actually accept an answer :-) – Jan Algermissen Sep 27 '11 at 16:22
  • Do you suggest to send users at a body? – kamaci Sep 27 '11 at 17:41
  • yeah. but uri ,body format and response code should be carefully designed. so if possible ,before you begin coding, read 'restful web services cookbook' by Sbbu Allamaraju , oreilly: p11.12, when to use post to merge multiple request ; and p11.13, how to support batch request – swanliu Oct 01 '11 at 00:42
2

I'm familiar enough with REST to recognize that using a POST to achieve a DELETE is a deviation from REST compliance. I'm not able to put my finger on the precise reason that's a good rule.

I suspect it may have something to do with either the feasibility of API-agnostic tooling (e.g. a dev tool that makes so assumptions about the state of an implementation based on givens about the verb definitions without needing to be configured to understand what specific API methods do) or the inability to return fine grained errors in the event of a partially successful delete, but those are just guesses and not really central to this question.

Swanliu's answer refers to use of URLs that represent a grouping construct as the target of a delete, but the example given, "/users/expired", suggests a fixed (and possibly system-defined) grouping. The more user-oriented case of an arbitrary collection still requires an enumeration at some point to achieve.

Issuing N DELETEs for a group of size N is not attractive, both because of the compound latency and lack of atomicity, but a REST DELETE may only target a single resource.

I think the best-practice implied by Swanliu's response might be to define a POST operation capable of creating a resource that becomes the new containment parent of the objects to delete. A POST can return a body, so the system in question can create manufacture a unique identifier for this non-domain grouping resource and return it to the client, which can turn around and issue a second request to DELETE it. The resource created by the POST is short-lived, but purposeful--it's demise cascades to the domain objects that were the desired target of a bulk delete operation.

> POST /users/bulktarget/create
> uid=3474&uid=8424&uid=2715&uid=1842&uid=90210&uid=227&uid=66&uid=54&uid=8
> ...
< ...
< 200 OK
< ae8f2b00e

> DELETE /users/bulktarget/ae8f2b00e
> ...
< ...
< 200 OK

Granted, two network exchanges is less desirable than just one, but given that the smaller bulk delete is two objects and would require two DELETE operations to address without anyhow, it seems like a fair tradeoff--think of it like you're getting every object beyond the second one free.

John Heinnickel
  • 308
  • 2
  • 8
1

My understanding of REST is that is exactly what you must do. If there is an alternative I would love to know too :)

If you don't want to send multiple delete requests, then you have to design a more coarse api. (this is why most APIs out there are RESTful, not REST)

Btw, I think you need RequestMethod.DELETE?

Daryl Teo
  • 5,394
  • 1
  • 31
  • 37
0

AFAIK the basic REST is for working with a single resource. I would go with a POST to the /user/ resource and a special deleteUsers body containing the IDs to delete.

ZeissS
  • 11,867
  • 4
  • 35
  • 50