Может ли http PUT изменить идентификатор? - PullRequest
1 голос
/ 06 июня 2019

В Restful API:

PUT /product/{id}

Может ли указанный выше запрос http указать другой идентификатор в его теле, чтобы фактически изменить идентификатор исходной записи (предположим, идентификатортехнически может быть изменено в нижележащем хранилище) .

Это, кажется, говорит о том, что Restful * идемпотент правило для PUT.
Но я не уверен насчетэто, (даже после поиска через Google) .

Есть идеи?

Ответы [ 2 ]

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

Прежде всего, PUT - это , указанное как:

Метод PUT запрашивает создание или замену состояния целевого ресурса на состояниеопределяется представлением, включенным в полезную нагрузку сообщения запроса.Успешное PUT данного представления предполагает, что последующее GET для этого же целевого ресурса приведет к отправке эквивалентного представления в ответе 200 (OK) .Однако нет никакой гарантии, что такое изменение состояния будет наблюдаемым, поскольку другие целевые ресурсы могут обрабатываться другими пользовательскими агентами параллельно или могут подвергаться динамической обработке исходным сервером до получения любого последующего GET.

По этому определению «перемещение» ресурса с помощью PUT будет нарушать спецификацию HTTP и, таким образом, REST , поскольку ресурс не может быть снова получен через тот же URI,в случае, если URI также должен отражать обновленный идентификатор, и перенаправление не выполняется.Однако вы можете использовать POST вместо этого, поскольку здесь полезная нагрузка обрабатывается в соответствии с собственной семантикой ресурса.Обратите внимание, что изменение фактической полезной нагрузки (состояния ресурса) не является реальной проблемой, но «замена» URI будет в соответствии со спецификацией

Согласно Fielding ресурса - это все, что можно назвать, например, определенный документ, изображение события, которое произошло где-то.Даже набор других ресурсов может быть самим ресурсом.Филдинг описал ресурс как отображение времени на набор сущностей или значений, которые эквивалентны.Здесь значением может быть представление ресурса и / или идентификаторы ресурса.Это означает, что ресурс может изменяться со временем.Такое поведение можно наблюдать ежедневно в Интернете, то есть

В главе 6.2 диссертации Филдинг говорит о том, как REST применяется к URI.

... Определение ресурса в REST основано на простой предпосылке: идентификаторы должны изменяться как можно реже .Поскольку в Интернете используются встроенные идентификаторы, а не серверы ссылок, авторам необходим идентификатор, который точно соответствует семантике, которую они намереваются в гипермедиа-ссылке, позволяющей ссылке оставаться статической, даже если результат доступа к этой ссылке может изменяться со временем .REST выполняет это, определяя ресурс как семантику того, что автор намеревается идентифицировать, а не значение, соответствующее этой семантике во время создания ссылки.Затем он оставляется на усмотрение автора, чтобы убедиться, что идентификатор, выбранный для ссылки, действительно идентифицирует предполагаемую семантику....

... ресурс может иметь много идентификаторов.Другими словами, могут существовать два или более разных URI, которые имеют эквивалентную семантику при использовании для доступа к серверу.Также возможно иметь два URI, которые приводят к тому, что один и тот же механизм используется при доступе к серверу, и, тем не менее, эти URI идентифицируют два разных ресурса, поскольку они не означают одно и то же.

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

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

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

Можно настроить (временное) перенаправление на «страницу» нового продукта, чтобы разрешить клиентам, которые все еще имеют более старую версиюURI продукта, чтобы по-прежнему взаимодействовать с этим ресурсом, а также получать информацию о новом местоположении.Это в основном позволит любой операции HTTP работать как прежде.Особенно из-за кэширования некоторые клиенты могут еще не знать об изменении местоположения, поскольку они могут получать еще более свежее представление в локальном или промежуточном кэше.В качестве такого перенаправления был бы разумный выбор.

В итоге:

  • с использованием PUT для "перемещения" ресурсов и создания различных целевых URI, следовательно, нарушает спецификацию HTTP,и, таким образом, отдых.Вместо этого следует использовать запасной вариант к POST.
  • избегайте включения внутреннего идентификатора продукта в URI, чтобы отделить идентификатор продукта от фактического URI, чтобы можно было повторно использовать URI, даже если внутренний идентификатор изменяется.Это может потребовать сопоставления на стороне сервера того, какой продукт представлен на каком URI.Это хорошо сочетается с Майком Амундсеном, который утверждал, что Ваша модель данных - это не ваша объектная модель, не ваша модель ресурсов, а не ваша модель обеспечения .
  • реализует (временное) перенаправление со старого URI на новый URI, чтобы позволить старым клиентам по-прежнему взаимодействовать с продуктом
1 голос
/ 06 июня 2019

Да, приведенный выше http-запрос может указать другой идентификатор в своем теле.

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

...