Идемпотентный 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

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