Подтвердить что ты не робот

Понимание REST: GET принципиально несовместим с любым счетчиком "числа просмотров"?

Я пытаюсь понять REST. В REST GET не должен запускать что-то транзакционное на сервере (это определение, на которое все согласны, оно имеет фундаментальное значение для REST).

Итак, представьте, что у вас есть такой веб-сайт, как stackoverflow.com(я так говорю, если у меня есть базовые сведения о SO, это не меняет ничего на мой вопрос), где каждый раз кто-то читает вопрос, используя GET, там также отображается некоторый дисплей, показывающий: "Этот вопрос был прочитан 256 раз".

Теперь кто-то еще читает этот вопрос. Счетчик теперь равен 257. GET является транзакционным, потому что количество просмотров увеличилось и теперь снова увеличивается. "Число просмотров" увеличивается в БД, и об этом не спорят (например, на SO всегда отображается количество просмотров любого вопроса).

Итак, является ли REST GET принципиально несовместимым с любым "количеством представлений", например функциональностью на веб-сайте?

Поэтому, если он хочет быть "RESTFUL", если главная страница SO перестает отображать простые HTML-ссылки, к которым обращаются с помощью GET или перестает отображать "этот вопрос был просмотрен x раз"?

Поскольку приращение счетчика в БД является транзакционным и, следовательно, "неустранимым"?

ИЗМЕНИТЬ, чтобы пользователи Google Googling могли получить некоторые указатели:

Из http://www.xfront.com/REST-Web-Services.html:

4. Все ресурсы, доступные через HTTP GET, должны быть свободными от побочных эффектов. То есть запрос должен просто вернуть представление ресурса. Вызов ресурса не должен приводить к изменению ресурса.

Теперь мне, если представление содержит "количество просмотров", оно является частью ресурса [и в SO "количество просмотров" вопрос имеет очень важную информацию], и доступ к нему определенно изменяет ресурс.

Это резко контрастирует, скажем, с истинным RESTFUL HTTP GET, как тот, который вы можете сделать на ресурсе Amazon S3, где ваш GET гарантированно не будет изменять ресурс, который вы получите.

Но я все еще очень смущен.

4b9b3361

Ответ 1

Важно то, что с точки зрения клиента GET безопасен (не имеет побочных эффектов) по определению и что клиент поэтому может безопасно звонить GET сколько угодно раз, не учитывая никаких побочных эффектов, которые могут иметь.

Что делает сервер, так это ответственность сервера. В случае счетчика просмотров сервер должен принять решение, если он считает обновление счетчика побочным эффектом. Обычно это не потому, что счетчик является частью семантики ресурса в первую очередь.

Однако сервер может решить НЕ увеличивать счетчик для определенных запросов, таких как GET с помощью искателя.

Ян

Ответ 2

IMO избегает обновления статистики в запросе GET, потому что "кто-то сказал это" догматично относится к реестру. Делайте то, что прагматично. Если это связано с обновлением счетчика при ответе на запрос GET, пусть будет так.

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

РЕДАКТИРОВАТЬ: Чтобы ответить на ваш вопрос о самоинкрементарном счетчике, спросите себя, какой контекст вы применяете. Ясно, что если вы определяете ресурс, называемый counterThatIncrementsItselfWhenBeingRead, то он либо:

  • Прерывает ReSTfulness, поскольку счетчик с расширением чтения является самопротиворечивым ресурсом, если единственным правилом является то, что GET никогда не может иметь побочных эффектов или
  • Просто отлично, учитывая другой контекст, в котором вы, например, берете очень короткий ресурс ресурса и учитываете прирост как что-то, что происходит после того, как вы прочитали ресурс (или, более того, при отладке владельца ресурса)

Независимо от разрешения, которое вы решите применить, проблема действительно в том, что такое ожидаемое поведение. IMO, счетчик, который увеличивается при чтении, должен увеличиваться при чтении. Я все еще получаю доступ к представлению ресурса, хотя и с очень коротким сроком службы, который, как я знаю, будет изменен мгновенно после того, как я его прочитаю. Там ничего не изменилось.

Ответ 3

Здесь вы смешиваете пару вопросов. Один запрос к интерфейсу REST может инициировать внутреннюю транзакцию. Однако эта транзакция должна начинаться и заканчиваться в рамках одного запроса.
То, что интерфейс REST не должен делать, заключается в том, что несколько независимых запросов участвуют в одной транзакции "двухфазное совершение".

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

Ответ 4

GET является только безопасным и идемпотентным в отношении ресурса, указанного в запросе, - это все, что нужно клиенту и должно быть связано с ним.

Самый простой способ подумать об этом - рассмотреть любой механизм, выполняющий такие подсчеты как посредника (то есть вы используете многоуровневое ограничение), который контролирует запрос/ответы и обновляет какой-то другой ресурс подсчета просмотров, а не сам фактический ресурс.

Ответ 5

Просто потому, что страница доступна через GET, не означает, что нет возможности увеличить счетчик. Например, вы можете использовать POST AJAX.

Я также считаю, что такая "пассивная" сделка, вероятно, может быть смело проигнорирована. Там существует большая разница между посещением URL-адреса и удалением объекта где-то, а также посещением URL-адреса и увеличением счетчика посещений. Мне было бы интересно услышать другие мнения по этому вопросу.

Изменить: Я думаю, что Håvard S и я в основном согласны с тем, что GET, запускающий счетчик, может быть технически не-RESTful, но не стоит беспокоиться.

Ответ 6

POST предназначен для отправки информации, которую клиент предоставляет на сервер. Это не происходит здесь, поэтому POST не требуется.

Чтобы поддерживать безгражданство взаимодействия с HTTP (которое, я считаю, является целью REST), GET не обязательно должен вызывать какие-либо изменения состояния; но требуется, чтобы он не скрывал состояния от клиента; то есть любое количество состояний с будущими последствиями для взаимодействия с HTTP будет необходимо закодировать в пространстве URL, чтобы клиент мог использовать его для удовлетворения будущих запросов.

Счетчик является частью состояния, если его значение повлияет на будущие взаимодействия - например, если после каждого миллионного приращения "закажите автобусную экскурсию, по которой мы будем пытаться продать вам недвижимость в Орландо" в. REST в основном говорит, что в таких случаях он должен быть частью пространства URL-адресов, поэтому состояние может поддерживаться явно как часть адресации - например, вы можете создать GET для URL-адреса, для которого строка? counter = $cnt добавляется (с $cnt значением счетчика).

Если нет, это просто часть представления - нет причин для клиента когда-либо кормить его или любую другую информацию, основанную на нем, обратно на сервер, поэтому нет необходимости, чтобы он присутствовал в URL (или где-либо еще). Вы показываете его и отбрасываете.

Ответ 7

Один момент, который вам нужно будет искать: запросы GET могут запускаться ботами, например. поисковые системы. Они бы исказили вашу статистику, если вы не разрешаете их.

Ответ 8

Еще одна мысль:

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

/question/2363294 → Get возвращает вопрос, но не увеличивает счетчик /question/ 2363294/readCount → Get возвращает текущий счетчик чтения /question/ 2363294/readCount → Опубликовать обновления счетчика чтения

Тогда мое приложение для приятного клиента просто публикует прочитанное, как только я действительно посмотрю на него. И не тогда, когда он был загружен, например. из-за предварительной выборки...