Идемпотентный PUT в конкурентной среде
контекст
У меня есть REST API, где несколько клиентов (приложений) могут обновлять состояние ресурса с помощью PUT. Например, этот ресурс является лампой, которую вы можете включить ON
или же OFF
,
Этот ресурс также автоматически обновляется системой, когда он обнаруживает, что произошел сбой в электроснабжении, что приводит к BROKEN
государство. Я хочу сделать различие между BROKEN
а также OFF
, лампа в BROKEN
нельзя повернуть ON
!
проблема
я использую PUT
способ сделать это, что-то вроде PUT http://address:port/my_lamp { "state": "ON"}
Но я не уверен, уважаю ли я идемпотентное свойство PUT
метод. На самом деле, у меня есть 3 случая:
- Лампа
ON
, Приведенный выше код приводит кON
государство. - Лампа
ON
, Приведенный выше код приводит кON
состояние.... круто! На данный момент идемпотентность все еще гарантирована:-)! - Лампа
BROKEN
, Приведенный выше код приводит к ошибке, как503 Service Unavailable
Вопрос
Я не уверен, чтобы правильно понять понятие идемпотентности. Поверьте мне, я много чего прочитал об этом, но все еще немного смущен.
В моем понимании несколько PUT
всегда приводит к одному и тому же состоянию ресурса: не гарантируется в моем случае из-за BROKEN
Но я также мог понять это по-другому: множественный PUT
всегда приводит к одному и тому же побочному эффекту: гарантировано, моя просьба либо произвести поворот ON
Либо ничего (для BROKEN
дело было уже в).
РЕДАКТИРОВАТЬ:
Я имею в виду: единственным побочным эффектом является поворотON
лампа, которая гарантирована (она либо включается, либо ничего не делает)Смотрите здесь: REST DELETE действительно идемпотент?
Который правильный? В зависимости от понимания, мой REST API обеспечивает идемпотентность или нет...
EDIT2:
Из определения W3CМетоды также могут обладать свойством "идемпотентности", заключающимся в том, что (кроме ошибок, связанных с ошибками или истечением срока), побочные эффекты от N > 0 идентичных запросов такие же, как и для одного запроса.
Могу ли я считать, что это ошибка, чтобы повернуть ON
лампа, когда она BROKEN
?
1 ответ
Идемпотентность означает, что в изолированной среде несколько запросов от одного и того же клиента не влияют на состояние ресурса. Если запрос от другого клиента изменяет состояние ресурса, это не нарушает принцип идемпотентности. Хотя, если вы действительно хотите убедиться, что запрос пут не переопределит изменения другим одновременным запросом от другого клиента, вы всегда должны использовать etags. Чтобы уточнить, запрос put должен всегда предоставлять etag (полученный из запроса get) последнего состояния ресурса, и только если etag является последним, ресурс должен обновляться, в противном случае должен быть поднят код состояния 412 (Precondition Failed). В случае 412 клиент должен снова получить ресурс, а затем попробовать обновить. Согласно REST, это жизненно важно для предотвращения гонки.
Чтобы разработать еще больше:-
Согласно W3C ( http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html), "методы также могут обладать свойством" идемпотентности "в том, что (помимо ошибок или проблем с истечением срока действия) побочные эффекты из N > 0 идентичные запросы такие же, как и для одного запроса.'
Получить запрос - {'state': 'ON'} Etag-заголовок (скажем)- 123 PUT-запрос - {'state': 'OFF'} Etag-заголовок - 123
Некоторая внутренняя активность меняет состояние так, что новым состоянием является {'state': 'BROKEN'}. В этом даже этот etag должен быть изменен, чтобы сказать 124.
запрос на поставку - {'state': 'ON'} Etag-header - 123. Поскольку заголовок etag изменился, возвращается ошибка 412, которая не нарушает идемпотентность api (заисключением ошибок или проблем с истечением срока действия).
Получить запрос - {'state': 'BROKEN'} Etag-заголовок - 124 Поместить запрос - {'state': 'ON'} Etag-заголовок - 124