5

In our project, a list of all books can be retrieved through REST:

GET http://server/api/books/

A specific book can be retrieved as following:

GET http://server/api/books/:id/

Deleting a specific book is easy:

DELETE http://server/api/books/:id/

Now, to my question: what should be the result of the following call:

DELETE http://server/api/books/

Obviously, all books are deleted. But should the resource books/ also be deleted? That is, after the request:

  1. should GET /books/ return 200 OK with an empty list? or
  2. should GET /books/ return 404 not found?

According to the specs, which says that the concrete URI will be gone afterwards, I'd go for the second option. However, this makes things complicated and unlogic, in my opinion. It makes more sense to have an empty list of books, instead of no books.

What do you think?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Appelsien S.
  • 271
  • 1
  • 2
  • 5

3 Answers3

2

If it makes you feel better, assume that the server has logic that recreates the books resource automatically after it has been deleted. :-)

I'd go for 200 OK and an empty list. If you really don't like that then create a new resource called /books/all

and do

DELETE /Books/all
Darrel Miller
  • 139,164
  • 32
  • 194
  • 243
  • Introducing /books/all makes sense. I would call it /books/@all though (if this is a valid URI, I don't know by head), to make it explicit that this isn't a real book. – Appelsien S. Jul 16 '11 at 16:40
  • In this solution, what will return GET /books/all? 204 no content? Something else? – Appelsien S. Jul 16 '11 at 16:54
  • @Appelsein You could return no content, you could return 405 - method not allowed, or you could redirect to `/books` – Darrel Miller Jul 16 '11 at 17:06
  • @Appelsein @ is a reserved character, maybe use underscore or ~ http://labs.apache.org/webarch/uri/rfc/rfc3986.html#reserved – Darrel Miller Jul 16 '11 at 17:07
  • Just to emphasize the problem with returning a 404: I typically add a link to the collection resource (/books) to allow the client to add a book (/books/new). No collection resource, no link. That seems like a problem for the application workflow. Anyway, this was a really good question. – John Howes Jul 16 '11 at 17:59
  • @Darrel Miller - thanks, makes sense. I would say that redirecting to /books/ is prefered. – Appelsien S. Jul 17 '11 at 09:16
  • @John Howes - I am not really following what you mean. Could you please provide more details? – Appelsien S. Jul 17 '11 at 09:17
  • 1
    @Appelsien REST is all about the links. Your resource at /books should provide links to allow your clients to interact with your /books resource (creating a new book is just one example of a link you might want to provide). If you DELETE /books and then start returning a 404, how will your client add new books? So you need to keep returning an empty list with a link to add new books. – John Howes Jul 17 '11 at 12:30
  • I see what you mean. But why would you want a /books/new/ (it is like /books/create/?) resource? Is allowing a POST to /books/ not enough? – Appelsien S. Jul 17 '11 at 13:01
1

I think allowing DELETE /books is too risky. Part of a well designed api is to avoid "easy" mistakes from api-client side. It could easily happen that in client code something is going wrong, accidently the id (e.g. empty-string variable) is missing and unintended DELETE /books is sent.

What I would do is to force the client to iterate through DELETE /books/{id} in case he wants to delete all books.

Maybe you can give more input on your use-case: I wonder how likely the use-case is that DELETE /books as root source called (it is quite radical to delete root resources). Maybe you are offering deleting a sub-resource, e.g. /user/{id}/shopping-cart/{id}/books. If it is a more "transient" resource (like shopping-cart is) deleting api for all books would make more sense.

Regarding your other question: For /books I would return 200 and empty list. In collection cases I much prefer empty-lists over 'null' values.

manuel aldana
  • 15,650
  • 9
  • 43
  • 50
  • Sorry, I wasn't very precise in my description of /books. In our project, it is indeed a transient collection resource, like the shopping-cart example you gave. In that sense, it makes sense to delete the whole collection. That said, returning 200 OK and answering with an empty collection (instead of 404) seems to be the consensus, even though it's a bit unlogic with respect to the HTTP DELETE semantics. – Appelsien S. Jul 17 '11 at 09:15
  • Yes, I also think if it is a transient + common thing then DELETE ..../books is perfectly fine. When thinking of a collection resource DELETE + 200 I think it can be logical when taking following phrase: "You are removing all books from the bookshelf, but the bookshelf is still there" – manuel aldana Jul 17 '11 at 10:51
  • I agree from a semantical point of view. However, the specifics of HTTP DELETE say that the resource behind the URI should be gone. This is not the case if you take your (very logical) assumption. Hence my question. That said, the pragmatic approach is probably best here. – Appelsien S. Jul 17 '11 at 11:03
0

However, this makes things complicated and unlogic

How? You are requesting that a resource be deleted. That resource is deleted. The result is that it isn't there any more.

If anything, it's confusing to have it still be present after you deleted it.

Jim
  • 72,985
  • 14
  • 101
  • 108
  • Following your logic, a question: imagine there is only one book left, with id 50. Now, DELETE /books/50/ is called. What should GET /books/ return? 200 OK or 404? – Appelsien S. Jul 16 '11 at 15:08
  • I agree. However, and this is my point, this would mean that /books/ can either return 404 (if DELETE /books/ was called) or 200 (if DELETE /books/id-of-last-book/ was called). This means that in our backend, we have to remember this. This makes it unnecessary complicated. Don't you agree? – Appelsien S. Jul 16 '11 at 15:59