Introduction
This is a follow up to How to design a RESTful collection resource? . I think the main problem of bulk updates of resources (and bulk deletion) is still unsolved in the provided answers. Hence this new question.
Let's suppose I have a collection resource of items
http://example.com/items
I can retrieve a single item
via its item_id
with
GET http://example.com/items/{item_id}
and request an update of a single item with
PUT http://example.com/items/{item_id}
Particularly nice about PUT
is: it is idempotent:
A request method is considered "idempotent" if the intended effect on the server of multiple identical requests with that method is the same as the effect for a single such request. Of the request methods defined by this specification, PUT, DELETE, and safe request methods are idempotent.
Problem
I want to update multiple items in one request.
I have several options that appear to be undoubtedly "RESTful" but have their drawbacks.
- request a
PUT
on the collection and send ALL items in the request. (too much overhead if only a small subset of the collection is actually being changed). - request a
PATCH
orPOST
on the collection (not idempotent).
As PUT
and DELETE
are the only idempotent methods and DELETE
is clearly not meant for this (cf. rfc7231 section 4.3.5) I need to stick to PUT
.
Questions
- How can I achieve this with a "RESTful" API avoiding the aforementioned drawbacks?
- Does the following proposed API comply with REST? If not, why? And which changes could make it work?
- Is this a case where I indeed can not or should not comply with REST?
Proposal
As a possible solution I came up with the following.
I add a resource for update requests which changes the items
collection.
http://example.com/updateitems
- It only permits/accepts
PUT
requests (is that RESTful?) withmultipart/mixed
. - The requests send a list of full representations of the items which are to be updated.
- The server then updates the database of items and returns a 204 (no content) with header links to the updated single items.
- As
GET
is not allowed, there is no "subsequent GET" request to that resource which might violate the obligation ofHTTP
'sPUT
to have an "equivalent representation" to thePUT
request's representation. (cf. rfc7231 section 4.3.4) - the server can implement the update in an idempotent way.
Problems with that approach:
I have not figured out yet how to make it HATEOAS compliant. Probably, there should be a "collection" link in every items/{item_id}
resource representation to the items
resource and an "edit" link which points to the updateitems
resource. Should I hide the possibility to PUT
a single item in order to point the clients toward the "bulk edit"? (cf. iana link relations)
It seems to me as if my approach is compliant with any REST or HTTP requirement that I can think of. However, I have the impression that I somehow misused the semantics and clients will have a hard time figuring out how to actually use this API.
Any thoughts? Thanks in advance!