2015-11-03 2 views
1

Я застрял в теоретической проблеме с REST.Способ HTTP POST обязательно идемпотент?

Представьте себе простой продукт API. База данных содержит один набор движений, ссылающийся на product, a quantity и status.

У меня есть одно предварительное условие: я не хочу, чтобы пользователи API манипулировали статусом. Значение состояния может быть reserved или confirmed.

Во-первых, я хочу создать бронирование продукта. Вот соответствующий URL путь и метод HTTP, чтобы представить, что:

[POST] /products/{product-id}/reservations

Это создает движение со статусом reserved и возвращает идентификатор созданного движения.

Теперь я хочу, чтобы подтвердить эту оговорку:

[POST] /reservations/{movement-id}/confirmations

В семантическом образом, мне кажется, что я создаю подтвержденное бронирование. Фактически, я просто меняю статус движения.

Итак, 2 вопроса:

  1. Мой второй POST идемпотентна. Я не смог найти информацию в RFC, но может ли POST быть идемпотентным?
  2. Вы видите лучший способ представить подтверждение?
+0

Лично я не часто вижу идемпотентные POST-реализации, потому что этот метод не должен использоваться так. Идемпотентный HTTP-метод - это метод HTTP, который можно назвать много раз без разных результатов. Если вы хотите использовать POST-запросы, просто убедитесь, что вызов его несколько раз не изменяет результат или просто использует другой метод, например PUT, чтобы изменять статусы, поскольку он используется для модификаций довольно часто. – Valdas

+0

Вы сказали «не следует». В RFC-терминах это значимое слово. Можете ли вы дать мне ресурс, подтверждающий это? В качестве альтернативы, я не думаю, что идемпотентность касается результатов, но больше о состоянии сервера (новый объект был создан в базе данных, ...). – Gnucki

+0

Говоря о запросе 'POST', в спецификации говорится, что это не идемпотент. Это означает, что идемпотентность не гарантируется. Однако это не означает, что вы _required_, чтобы гарантировать, что несколько запросов «POST» не дают того же результата, что и выдача только одного. Поэтому 'POST' _may_ будет идемпотентным, но в отличие от' PUT', спецификация не гарантирует его. «PUT» действительно является более подходящим выбором здесь. – Evert

ответ

1

Я бы использовал PUT вместо этого. например PUT /reservations/{movement-id}/status "confirmed".

примечание:

Это не важно, что ваш пост является тождественным, так как удалить ссылку после резервирования было подтверждено (HATEOAS), так что вероятность очень мала, что 2 подтверждения прибыть для того же отеля. В любом случае, я думаю, что PUT лучше подходит.

+0

Спасибо за ваш ответ. Конечно, я подумал о вашем решении, но, как я сказал в своем вопросе, я не хочу, чтобы пользователь API определял новые статусы. В вашем решении статус может быть любым, чего хочет пользователь. Более того, я предпочел бы более семантическое использование API.Я не сказал, что я использую какую-то систему гипермедиа, но вопрос был больше о том: может ли запрос POST быть идемпотентным или нет? – Gnucki

+2

@Gnucki Вы должны проверить статус. POST обычно не является идемпотентным, но вы можете использовать его идемпотентным способом, если хотите. По крайней мере, я не нашел никаких ограничений по этому поводу в стандарте HTTP, только вам нужно использовать 200 или 204 вместо 201, если новый ресурс отсутствует. Я не предлагаю вам использовать POST таким образом, это исключение для случая, когда вы не нашли лучший HTTP-метод, а не правило. – inf3rno

+0

Хорошо. Спасибо за советы и поиск! – Gnucki

Смежные вопросы