Question

There is /group/1 and /group/2, and /item/42 is a member of /group/1. I would like to remove /item/42 from /group/1 and put it into /group/2. My current solution is this:

GET    /group/1/item/42   => Get the item from the first group
POST   /group/2/item      => Create a clone of the item in the 2nd group
DELETE /group/1/item/42   => Delete the original item from the 1st group

There are (at least) two serious problems with this solution:

  1. If the client stops before the DELETE, the item will become a member of both groups.
  2. The ID of the item won't be the same in /group/2, which looks as if the item would lose its identity.

How should I redesign the API if I want to change an item's group membership in a single step (with retaining its identity, if possible)?

Was it helpful?

Solution

In your case, I would not use the URI to link items to groups.

If items to groups are 1 to n-relationship, every item should have a link (e.g. a database foreign key) to its group.

Therefore, your URI-space could be much simpler:

./[groups|items]/{id}

The RESTful way is to modify the item resource with a POST.

POST /items/42 { group: 2 }

In this case, your backend identifies the request as an update to an existing resource.

Here are a few demonstrations how the API could work.

GET /items --list of all items by IDs
GET /groups --list of all groups by IDs
GET /items/42 --item 42 properties

POST /items { id: 33, name: "Cool Item", group: 2} -- adds a new item, linked to group 2
PUT /groups/4 { id: 4, name: "Hot group"} --adds a new group
POST /groups/4 {name: "Cool group" } --updates the name of group 4
POST /items/33 { group: 4 } --moves the new item 33 to group 4

GET /items?group=4 --list of all items belonging to group 4

You can use POST instead of PUT if you want.

OTHER TIPS

If you need an atomic operation, I would consider

POST /group/2?moveFrom=/group/1/item/42
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top