REST API - изменение членства в группах

Есть /group/1 а также /group/2, а также /item/42 является членом /group/1, Я хотел бы удалить /item/42 от /group/1 и положить его в /group/2, Мое текущее решение таково:

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

Есть (по крайней мере) две серьезные проблемы с этим решением:

  1. Если клиент останавливается до DELETE, элемент станет членом обеих групп.
  2. Идентификатор предмета не будет таким же в /group/2, который выглядит так, как будто элемент потеряет свою идентичность.

Как мне изменить дизайн API, если я хочу изменить членство в группе за один шаг (с сохранением его идентичности, если это возможно)?

2 ответа

Решение

В вашем случае я бы не использовал URI для связи элементов с группами.

Если элементы для групп имеют отношение от 1 до n, каждый элемент должен иметь ссылку (например, внешний ключ базы данных) на свою группу.

Следовательно, ваше URI-пространство может быть намного проще:

./[groups|items]/{id}

RESTful способ состоит в том, чтобы изменить ресурс элемента с помощью POST.

POST /items/42 { group: 2 }

В этом случае ваш сервер идентифицирует запрос как обновление существующего ресурса.

Вот несколько демонстраций того, как API может работать.

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

Вы можете использовать POST вместо PUT, если хотите.

Если вам нужна атомная операция, я бы рассмотрел

POST /group/2?moveFrom=/group/1/item/42
Другие вопросы по тегам