S3 REST API и метод POST

Я использую AWS S3 REST API, и после решения некоторых раздражающих проблем с подписью, похоже, работает. Однако, когда я использую правильный глагол REST для создания ресурса, а именно POST, Я получил 405 method not allowed, Тот же запрос отлично работает с методом PUT и создает ресурс.

Я делаю что-то не так, или AWS S3 REST API не полностью REST-совместимый?

4 ответа

Решение

Да, вы не правы в сопоставлении CRUD и HTTP-методов.

Несмотря на популярное использование и широко распространенное заблуждение, в том числе высоко оцененные ответы здесь о переполнении стека, POST не является "правильным методом создания ресурса". Семантика других методов определяется протоколом HTTP, но семантика POST определяется самим целевым типом носителя. POST - это метод, используемый для любой операции, которая не стандартизирована по протоколу HTTP, поэтому его можно использовать для создания, но также можно использовать для обновлений или чего-либо еще, что еще не сделано каким-либо другим методом. Например, неправильно использовать POST для извлечения, так как для этого стандартизирован GET, но хорошо использовать POST для создания ресурса, когда клиент по какой-то причине не может использовать PUT.

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

На неформальном языке каждый метод говорит серверу:

  • POST: возьмите эти данные и примените их к ресурсу, идентифицированному данным URI, следуя заданным вами правилам для типа носителя.

  • PUT: заменить все данные, идентифицированные данным URI, этими данными, игнорируя все, что там уже есть, если что-нибудь.

  • PATCH: если ресурс, идентифицированный данным URI, все еще находится в том же состоянии, в котором он находился в прошлый раз, примените этот diff к нему.

Обратите внимание, что создание или обновление не упоминается и не является частью семантики этих методов. Вы можете создавать с помощью POST и PUT, но не PATCH, поскольку это зависит от текущего состояния. Вы можете обновить с любым из них, но с PATCH у вас есть условное обновление до состояния, из которого вы хотите обновить, с PUT вы обновляете, заменяя весь объект, так что это идемпотентная операция, и с POST вы просите сервер выполнить это по заранее определенным правилам.

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

+--------------------------------------+---------------------+
|                 POST                 |         PUT         |
+--------------------------------------+---------------------+
| Neither safe nor idempotent Ex: x++; | Idempotent Ex: x=1; |
+--------------------------------------+---------------------+

Добавить в @Nicholos

Из http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

СООБЩЕНИЕ:

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

Действие, выполняемое методом POST, может не привести к ресурсу, который может быть идентифицирован с помощью URI. В этом случае либо 200 (ОК), либо 204 (Нет содержимого) - это соответствующий статус ответа, в зависимости от того, включает ли ответ объект, описывающий результат.

Если ресурс был создан на исходном сервере, ответ ДОЛЖЕН быть 201 (Создан)

ПОЛОЖИЛ:

Метод PUT запрашивает, чтобы вложенный объект был сохранен под предоставленным Request-URI. Если Request-URI ссылается на уже существующий ресурс, вложенный объект СЛЕДУЕТ рассматривать как модифицированную версию, находящуюся на исходном сервере. Если Request-URI не указывает на существующий ресурс, и этот URI может быть определен как новый ресурс запрашивающим пользовательским агентом, сервер-источник может создать ресурс с этим URI. Если новый ресурс создан, сервер происхождения ДОЛЖЕН проинформировать пользовательский агент через ответ 201 (Создано). Если существующий ресурс изменен, то должны быть отправлены коды ответа 200 (ОК) или 204 (Нет содержимого), чтобы указать успешное завершение запроса.

IMO PUT может использоваться для создания или изменения / замены вложенного объекта.

В исходной спецификации HTTP ресурс, указанный в полезной нагрузке запроса POST, "считается подчиненным указанному объекту" (т. Е. URL запроса). Ранее TimBL сказал (не может найти ссылку), что он был смоделирован по методу с тем же именем в NNTP.

Другие вопросы по тегам