Понимание REST: действительно ли GET принципиально несовместим с любым счетчиком «количества просмотров»? - PullRequest
13 голосов
/ 02 марта 2010

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

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

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

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

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

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

РЕДАКТИРОВАТЬ только для того, чтобы люди, прибегая к помощи Google, могли получить несколько указателей:

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

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

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

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

Но тогда я все еще в замешательстве.

Ответы [ 8 ]

7 голосов
/ 02 марта 2010

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

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

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

Ян

7 голосов
/ 02 марта 2010

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

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

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

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

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

5 голосов
/ 02 марта 2010

Вы смешиваете пару вопросов здесь. Один запрос к интерфейсу REST МОЖЕТ инициировать внутреннюю транзакцию. Однако эта транзакция должна начинаться и заканчиваться в рамках одного запроса.
Интерфейс REST не должен делать, чтобы несколько независимых запросов участвовали в одной и той же внутренней транзакции «двухфазного принятия».

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

3 голосов
/ 02 марта 2010

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

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

1 голос
/ 28 мая 2010

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

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

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

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

1 голос
/ 02 марта 2010

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

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

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

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

1 голос
/ 02 марта 2010

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

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

Редактировать: Я думаю, что Ховард С и я в основном согласны, что GET, который запускает счетчик, может быть технически не-RESTful, но не о чем беспокоиться.

0 голосов
/ 02 марта 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...