Параметр пути против параметра запроса в запросе ИСПРАВЛЕНИЯ

#rest #http

Вопрос:

Я знаю, что по этой теме было задано много вопросов о лучших практиках, но я не могу найти именно то, что ищу. Допустим, я хочу иметь конечную точку для присоединения к чату или выхода из него. Моя мысль состояла в том, чтобы иметь запрос, подобный:

PATCH /api/chatroom/{roomId}?action=join|leave

Мне это кажется надежным, потому что ИСПРАВЛЕНИЕ обычно используется для частичного обновления ресурса. В этом случае я обновляю ресурс чата, либо удаляя, либо добавляя участника. Однако мне это не нравится по двум причинам:

  1. Наличие параметра запроса, подобного action , кажется немного неуклюжим. Пользователь API должен знать возможные значения для action , а недопустимые значения должны быть явно обработаны на стороне сервера.
  2. Обработка ошибок для join vs совершенно иная leave . Запрос на объединение вернет ошибку, если пользователь не был приглашен в чат. С другой стороны, запрос на оставление вернет ошибку, если пользователь не является участником чата. Эти различия заставляют меня чувствовать, что это должны быть отдельные конечные точки.

Было бы предпочтительнее иметь две конечные точки, подобные этой?

PATCH /api/chatroom/{roomId}/join и PATCH /api/chatroom/{roomId}/leave

Это ощущается хуже, потому join что и leave не являются ресурсами. Тем не менее, мне также нравится, что это разделяет вещи на две конечные точки. Каков наилучший способ сделать это?

Ответ №1:

Мне это кажется надежным, потому что ИСПРАВЛЕНИЕ обычно используется для частичного обновления ресурса.

ДА… но мы обычно не вкладываем новые ресурсы только для их исправления.

TL; DR: можно использовать POST. Это то, что мы делали в Интернете, когда все было HTML и forms.

ИСПРАВЛЕНИЕ, как и PUT, следует понимать как сообщение POST с дополнительными ограничениями. POST предоставляет клиентам общего назначения очень мало информации о том, что происходит; но ИСПРАВЛЕНИЕ более конкретное — в исправлении говорится, что мы предлагаем редактирование целевого запроса, а полезная нагрузка представляет собой «документ исправления», который описывает изменения в представлении.

Другими словами, PATCH (например, PUT) — это метод, который мы бы использовали, если бы пытались исправить орфографическую ошибку на веб-странице.

Ключевая идея хорошо описана Webber 2011: ИСПРАВЛЕНИЕ является частью передачи документов общего назначения по сетевому домену. Полезные бизнес-действия (например, присоединение к чатам и выход из них) являются побочными эффектами манипулирования документами в модели ресурсов.

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

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

 POST /api/chatroom/12345 HTTP/1.1
Content-Type: application/x-www-form-urlencoded

action=joinamp;user=Bob
 

Если бы /api/chatroom/12345 был ресурсом с представлением JSON, то мы могли бы достичь аналогичного результата, исправив список участников в ресурсе chatroom

 PATCH /api/chatroom/12345 HTTP/1.1
Content-Type: application/json-patch json

[
{ "op": "add", "path": "/participants", "value": "Bob" }
]
 

также лучше включить информацию об исправлении в тело, а не URL.

URI идентифицирует ресурс; документ исправления описывает предлагаемые изменения в ресурсе, идентифицируемом URI.


Я должен склоняться к использованию ИСПРАВЛЕНИЯ на самом ресурсе и передавать JSON-представление изменений, которые я ищу?

если удаленная разработка является правильным интерфейсом для вашего контекста.

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

Это означает, что вывод предполагаемой «деловой активности» означает идентификацию изменений в документах, а затем выполнение правильных действий. Сравните это с POST, который больше подходит для «Я собираюсь сказать вам, что я хочу, вы выясняете, как должен измениться документ».

Комментарии:

1. Чтобы уточнить, у меня есть другие конечные точки в /api/chatroom/{roomId} , такие как GET /api/chatroom/{roomId} . Следовательно, из вашего ответа я понял, что я должен склоняться к использованию PATCH на самом ресурсе и передавать JSON-представление изменений, которые я ищу? Похоже, вы говорите, что также лучше включить информацию о патче в тело, а не URL.

2. Взгляните на изменения, дайте мне знать, если это имеет смысл.

3. Да, это помогло, спасибо!

Ответ №2:

 PATCH /api/chatroom/{roomId}/join and PATCH /api/chatroom/{roomId}/leave
 

Я тоже ссылаюсь на это из-за единой ответственности.

Ресурсы не всегда требуются, манипулирование чем-либо тоже нормально.

 /api/cart/empty-all
/api/cart/remove-all
...