Я нарушаю RESTfulness при использовании POST как UPDATE или CREATE

Учитывая требования других отделов для нашего REST API, они хотели бы использовать POST не только для CREATE, но и для UPDATE ИЛИ CREATE. Я знаю, что в RESTful API PUT может или должно быть использовано для этого, но поскольку клиенты должны обновлять информацию, которая используется для создания URI, мы не можем это использовать. Это изменит URI и сделает PUT не идемпотент больше... (старый URI не будет существовать после первого PUT).
tl; dr мы не можем использовать PUT

В спецификации HTTP/1.1 POST определяется как

Метод POST используется для запроса, чтобы исходный сервер принял объект, заключенный в запрос в качестве нового подчиненного ресурса идентифицированный Request-URI

но также

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

Чтобы остаться RESTful, я бы объяснил функциональность обновления как удаление старого элемента, а затем создание нового, что было бы приемлемой функциональностью для POST, я бы сказал.

Мы вернем #201, когда создание было успешным, и #200, когда это было просто обновление.


В нашем API "возможно" обращаться к правильному элементу без URI (например, для его обновления с помощью POST), потому что все части первичного ключа сборки URI находятся в теле ресурса, поэтому API знает, какой элемент клиент хочет получить доступ.


Пример

(Это всего лишь пример поведения для POST, а не для структуры данных ресурса. Конечно, использование PUT было бы совершенно правильным для /cars/)

POST /cars/ HTTP/1.1
<car>
    <id>7</id>
    <status>broken</status>
</car>

ответ: #201
и затем

POST /cars/ HTTP/1.1
<car>
    <id>7</id>
    <status>fine</status>
</car>

ответ: #200
теперь a GET на /cars/7 вернет следующее:

<car>
    <id>7</id>
    <status>fine</status>
</car>

Ответ 1

"Нарушение RESTfulness" строго не определено.

Хорошей ссылкой на степени REST-подобного поведения в интерфейсе является модель зрелости Ричардсона, которая разделяет степени поддержки идеалов REST на 4 уровня (при этом 0 "не REST вообще" и 3 "полностью REST", но вряд ли кто-нибудь это делает ")

Ваш выбор немного ломается с RESTful HTTP-дизайном на уровне 2 в этой модели. Тем не менее, это тот компромисс, с которым приходится сталкиваться многим проектам в реальном мире.

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

Как личное мнение, я думаю, что если вы останетесь самосогласованными при обработке различных методов и маршрутов HTTP и четко сформулируете это изменение в ожиданиях, то вы можете разумно называть свой API "RESTful". Я думаю, что код ответа, разделенный на 200/201, достаточен для написания самосогласованного клиента. Хотя я бы предпочел видеть и создавать и обновлять как PUT здесь, это не то, что могло бы вызвать у меня больше минуты паузы.

Вы можете подумать о поддержке обновления или создания на маршруте сбора (POST /cars в вашем примере), как предлагается, плюс обновление маршрута элемента (POST /cars/7). Концепция "обновления или создания" достаточно распространена в структурах баз данных и ORM, что было бы легко понять. Клиент мог также использовать последний маршрут только для обновления, уверенно, что он не случайно автоматически создаст новую запись.

Ответ 2

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

Методы могут также обладать свойством "идемпотенции" в этом (в сторону от ошибок или ошибок истечения) побочные эффекты N > 0 одинаковы запросы такие же, как и для одного запроса.

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

Метод POST используется для запроса, чтобы исходный сервер принял объект, заключенный в запрос в качестве нового подчиненного ресурса идентифицированный Request-URI

В этом случае вы не создаете новый ресурс, вы просто добавляете новый идентификатор ресурса и удаляете старый идентификатор ресурса. Поэтому POST не подходит.

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

Это может означать все, что вы хотите... Ppl использует POST для не творческих целей, когда у них нет опций, но вы, конечно, не знаете.

В нашем API "возможно" обращаться к правому элементу без URI (например, для обновления его с помощью POST), поскольку все здание URI первичные ключевые части находятся в теле ресурса, поэтому API знает, какие который клиент хочет получить.

Для идентификации ресурсов вам необходимо использовать IRI (URL), если вы не хотите нарушать ограничение однородного интерфейса (идентификация ресурсов).

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

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

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