Правильный метод HTTP для обновления ресурса без воздействия на подресурсы в REST - PullRequest
3 голосов
/ 06 июня 2011

Давайте предположим, что у меня есть две сущности - команда проекта и сотрудник. Каждый сотрудник может входить в состав нескольких команд, и в каждой команде может быть несколько сотрудников. Мне нужно предоставить REST API для управления командами, сотрудниками и отношениями между ними.

Я выделил 3 ресурса - команду, сотрудника и участника (связь между командой и сотрудником), который является подресурсом команды. Причина, по которой я выбрал член в качестве подресурса, основана исключительно на жизненном цикле этого ресурса. Каждый раз, когда команда удаляется, участники удаляются, так как они не имеют значения вне самой команды.

Я выставляю следующие API (соответствующие):

  • POST /teams создает новую запись команды с именем, идентификатором отдела и т. Д.
  • POST /teams/{name}/members создает связь между командой, идентифицированной по имени, и конкретным сотрудником, поэтому входные данные содержат идентификатор сотрудника

Мне также нужно предоставить API для обновления идентификатора отдела и других атрибутов команды в одном запросе. Похоже, PUT - естественный выбор, но семантика PUT довольно ясна - мне нужно заменить весь ресурс, что в данном случае означает также замену всех подресурсов членов.

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

Ответы [ 3 ]

5 голосов
/ 06 июня 2011

Похоже, PUT - это естественный выбор, но Семантика PUT довольно ясна - я должны заменить весь ресурс, который в этом случае означает замену всех суб-ресурсы участников.

Я никогда не слышал, чтобы кто-то делал эту связь раньше. Если делать PUT /Foo, по моему мнению, это абсолютно ничего не говорит о /Foo/bar. Тот факт, что к ресурсу можно обращаться через иерархическое пространство URI, не означает каких-либо дополнительных отношений между этими ресурсами.

Я слышал, что люди делают противоположный сценарий, когда вы делаете PUT /Foo/bar, и если сервер знает, что это повлияет на состояние /Foo, вы можете включить заголовок Content-Location, который указывает на /Foo, чтобы разрешить интеллектуальное кэши для аннулирования /Foo. Однако Content-Location необходим для явного создания взаимосвязи между двумя ресурсами.

2 голосов
/ 06 июня 2011

В идеале вы должны использовать метод PATCH, но не уверены, какая реализация его использует.Если нет, то вам следует пойти по циклу GET -> локально изменить -> PUT.

Также, в зависимости от вашего дизайна, вы можете интерпретировать, что подресурсы не являются частью самого ресурса.Например, содержимое командного ресурса может содержать ссылку на список членов ресурса, скажем «/team/{name}/members», но не содержащий весь список в качестве элемента.

0 голосов
/ 06 июня 2011

Я думаю, вы отвечаете на свой вопрос.PUT предлагает создание ресурса, POST используется для обновления.

Еще один способ взглянуть на это состоит в том, что каждое изменение ресурса действительно «создает новую версию» ресурса.каждое создание, обновление и удаление добавляет новую версию с новыми свойствами, и эта версия имеет свой уникальный идентификатор.Когда вы PUT используете новую версию существующего ресурса, старый ресурс остается, так что новый ресурс может наследовать его.Попытки PUT новой версии в более старой версии, когда более новая версия этого ресурса уже существует, будут возвращать перенаправление вместо успеха, как и некоторые GET запросы (те, которые не указывают, что они на самом деле ищутдля старой версии)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...