Обновление REST Best Practice: PUT collection /: идентификатор без идентификатора в теле VS PUT collection / с идентификатором, включенным в тело - PullRequest
0 голосов
/ 19 марта 2020

Я пытаюсь определить соглашения по запросам PUT для проекта, над которым я работаю, и я не могу решить, какой из этих двух вариантов является наиболее подходящим или если это вопрос личных предпочтений. Я видел несколько статей о лучших практиках REST, и кажется, что id всегда подразумевается как часть URL для запросов PUT.

Цель: Обновить ресурс с помощью API REST.

Параметры

  1. PUT collection / {id} - без идентификатора в теле
  2. PUT collection / - без идентификатора в URL, только в теле

Вопросы

  1. Какое соглашение я должен использовать?
  2. Почему?
  3. Существуют ли общепринятые плюсы и минусы для каждого варианта?

Ответы [ 3 ]

0 голосов
/ 19 марта 2020

Важно убедиться, что вы понимаете семантику PUT

Успешное PUT данного представления предполагает, что последующее GET для того же целевого ресурса приведет к в эквивалентном представлении, отправляемом в ответе 200 (ОК).

Другими словами

PUT /collection

означает «заменить представление / collection на представление, включенное в это сообщение ".

Так что это правильный запрос, который нужно использовать, если вы пытаетесь изменить представление самого ресурса коллекции, и неправильный выбор, если вы пытаетесь изменить представление чего-то другого.

Например, если представление коллекции представляло собой список описаний ее элементов, то вы можете использовать PUT, чтобы заменить список другим.

GET /collection

200 OK

[1, 2, 3]

PUT /collection

[4, 5]

204 No Content

GET /collection

[4, 5]

Другими словами, из С точки зрения REST, «коллекции» используют точно такие же сообщения, с той же семантикой, что и любой другой ресурс.

Если то, что вы пытаетесь описать, является изменением какого-либо другого ресурса, то вы используете идентификатор для этого ресурса

PUT /collection/1

Теперь, если этот идентификатор "1" должен быть в представлении ? Это зависит - но вот базовое правило c: потребители (и промежуточные компоненты) никогда не должны пытаться извлечь информацию из URI, только из представлений. Таким образом, если вашим потребителям в потреблении требуется этот «1», то он должен присутствовать в представлении ресурса.

PUT в этом смысле просто двойственное значение GET - если GET должен включать информацию в представлении, предоставленном ответом, тогда PUT должен включить ту же самую информацию в представление, предоставленное запросом.

Может быть полезно подумать о содержимом файла - мы помещаем информацию, необходимую читателю, в файл, имя файла / путь просто говорит читателю, как его найти. Или, если вы думаете о Hash / Map / Dictionary - ключ используется для получения значений на карте и за ее пределами, но информация находится в значении.

Если я не планирую поддержка полной замены коллекции

... тогда PUT /collection является неправильным , потому что мы все согласились (через RF C 7231), что PUT означает «замена» .

Можно использовать POST вместо PUT, если вы пытаетесь манипулировать /collection каким-то нестандартным способом.

Если вы собираетесь чтобы манипулировать представлением коллекции, но вы хотите описывать вставки и удаления, а не отправлять все представления каждый раз, вы можете использовать PATCH с каким-то патчем, описывающим ваши изменения.

0 голосов
/ 19 марта 2020

REST опирается на семантику своего транспортного уровня, в большинстве случаев HTTP. HTTP по своей сути является просто системой удаленного управления документами, которая просто заботится об отправке файлов из одного места в другое без сохранения состояния. Как отметил Джим Уэббер , любые заключенные бизнес-правила в основном являются побочным эффектом фактического управления документами.

Таким образом, вы должны сначала рассмотреть свою задачу в смысле обычного управления документами. Вы помещаете файл куда-нибудь и заменяете любое существующее представление. Это то, что на самом деле означает PUT. Поэтому идентификатор в документе - не лучшая идея, если он не является частью фактического содержимого документа.

Независимо от того, содержит ли URI отдельный идентификатор или нет, это не имеет значения в архитектуре REST. Более формально, весь URI является идентификатором самого ресурса независимо от того, добавили ли вы какой-либо дополнительный идентификатор в URI или нет. URI не должен ничего рассказывать клиенту ни о ресурсе, ни о его семантике, ни о какой-либо иерархии. Согласование типа контента и отношения ссылки существуют для.

Филдинг даже заявил, что

API REST не должен определять фиксированные имена ресурсов или иерархии (очевидная связь клиента и сервера). Серверы должны иметь свободу управления своим собственным пространством имен. Вместо этого позвольте серверам инструктировать клиентов о том, как создавать соответствующие URI, например, в формах HTML и шаблонах URI, определяя эти инструкции в типах мультимедиа и отношениях ссылок. [Ошибка здесь подразумевает, что клиенты принимают структуру ресурса из-за внеполосной информации, такой как спецификация домена c, которая является ориентированным на данные эквивалентом функциональной связи RPC]. ( Источник )

Причина, по которой многие разработчики помещают идентификаторы в свои URI, заключается в том, что на стороне сервера они маркируют URI и используют соответствующие токены для выполнения поиска в БД на сервере. соответствующие сегменты. Причина, по которой не следует указывать ieID продукта в URI, заключается в том, что при изменении идентификатора по какой-либо причине URI изменяется как последующее событие, хотя фактический продукт остается совершенно неизменным. Т.е. вспомните о продукте A000123, который внезапно упоминается как P12300001, но больше ничего не изменилось. Это могло произойти из-за слияния компаний или тому подобного (такой инцидент был в прошлом, т. Е.). В архитектуре REST URI, такие как /products/A000123 и /products/P12300001, относятся к двум разным ресурсам и, следовательно, к двум разным продуктам, даже если они могут возвращать идентичный контент. Если бы вместо идентификатора продукта использовался бы другой, произвольный UUID, что привело бы к внутреннему сопоставлению этого UUID с продуктом. Если бы URI мог остаться таким же, как в основном продукт, то же самое.

I До сих пор перефразирую ваш вопрос: «Действительно ли вашему клиенту нужен идентификатор?». В совершенной REST-архитектуре сервер на каждом этапе процесса обучает клиента тому, что клиент может и может делать. Поскольку REST - это просто обобщение концепций, используемых в Интернете, весь дизайн можно смоделировать так, как если бы взаимодействие происходило в Интернете, а затем использовать те же концепции для взаимодействия приложений. Подумайте о произвольном клиенте, управляемом человеком или машиной, который должен заказать какой-то товар у Amazon, т. Е. Клиент запрашивает у Amazon список продуктов, соответствующих некоторым критериям поиска, сервер отвечает страницей, содержащей ссылки на более или менее подходящие продукты клиента можно углубиться, чтобы узнать детали каждого продукта. При желании клиент может добавить товар в свою корзину, нажав на ссылку. На самом деле все равно, как выглядит URI, он просто вызвал его, поскольку некоторые метаданные (имя отношения текста или ссылки) указали, что это добавит товар в корзину. Ни в коем случае клиент действительно не интересуется фактическим номером продукта, поэтому зачем добавлять его, кроме как дать клиенту (человеку, взаимодействующему) возможность использовать его по реферальным причинам при взаимодействии по электронной почте со службой поддержки и т. П.

В конце концов, независимо от того, используете ли вы идентификаторы в URI или полезную нагрузку тела, это ваш личный выбор. В зависимости от вашего варианта использования предоставление идентификаторов клиентам может даже не потребоваться, поскольку вся модель взаимодействия, используемая в REST (и в Интернете), просто использует URI для извлечения следующей «страницы» данных и подсказки о том, использовать ли этот URI хранится в метаданных, сопровождающих URI, таких как сводный текст содержимого ссылок, как в случае HTML ссылок, или как часть имен отношений ссылок, которые определяются медиа-типами, Веб-ссылки расширения (например, Dublin Core ) или органом по стандартизации .

0 голосов
/ 19 марта 2020

PUT заменяет ресурс по указанному адресу.

Так что если вы PUT collection, я бы ожидал, что вся коллекция будет перезаписана.

Так что это не совсем мнение важно, в данном случае это просто неправильно.

...