Когда использовать GET против PUT, и что должно произойти, если введен URI PUT?
(Это не совсем специфично для Rails, но я буду использовать конструкции Rails, чтобы задать вопрос).
TL; DR
Что должно произойти, когда пользователь вводит URI в адресную строку, которая на самом деле является операцией PUT, а не GET?
подробности
Давайте предположим, что у нас есть веб-датчик, который хранит копию своего последнего прочитанного значения в базе данных (для эффективности), но пользователь может запросить обновление для обновления кэшированного значения. Итак, вот как могут выглядеть маршруты:
VERB | URI Pattern | Effect
-----+-------------------+------------------------------------
GET | /gauge/:id | show the cached state of gauge #id
PUT | /gauge/:id/update | update the cached state of gauge #id
Я выбрал GET
чтобы показать кэшированное состояние датчика, так как вы можете выполнить любое количество GET, и результаты никогда не изменятся. В терминологии http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html операция GET идемпотентна. таким образом GET /gauge/33
извлечет кэшированное значение датчика #33.
Как я понимаю RFC2616, я ДОЛЖЕН использовать PUT
обновить локальное состояние, так как состояние может меняться при каждом вызове: оно не идемпотентно. Заявлено иначе PUT /gauge/33/update
вызывает побочный эффект в базе данных.
А теперь: останови меня прямо здесь, если я неправильно истолковываю RCF2616, и я тихо уйду.
Вопрос
Мой вопрос действительно прост: что должно произойти, если пользователь наберет /gauge/33/update
в адресную строку браузера? Что представляет на сервер как GET /gauge/33/update
, но нет подходящего маршрута.
Является ли обычной практикой установка маршрута, включающего в себя как GET, так и PUT для одного и того же шаблона URI? То есть я мог бы настроить свою таблицу маршрутизации как:
VERB | URI Pattern | Effect
-----+-------------------+------------------------------------
GET | /gauge/:id | show the cached state of gauge #id
PUT | /gauge/:id/update | update the cached state of gauge #id
GET | /gauge/:id/update | perhaps the same as PUT (but see below)
Меня беспокоит такой подход, если пользователь вызывает GET /gauge/33/update
два (или более) раза подряд сервер может решить, что - поскольку GET сигнализирует об идемпотентной операции - ему фактически не нужно выполнять обновление.
Я просто педантичен? Или я неправильно истолковываю RFC2616?
2 ответа
Это представляется серверу как GET /gauge/33/update, но нет подходящего маршрута.
Если маршрута нет, он просто загрузит ошибку 404 (или 405 согласно Jasen). Вы не можете отправить запрос PUT на сервер, введя адрес в адресной строке браузера.
При использовании методов пути rails вы захотите отправить пользователя в действие show, а не в метод обновления. Так что вы бы использовать gauge_path(@gauge)
генерировать путь, который приведет к /gauge/123
(Предполагая, что это идентификатор датчика в БД. Единственный раз, когда вы захотите сделать пут, будет в форме при обновлении датчика, например, так:
Который создаст форму с методом, установленным как PUT.
Проверьте это для получения дополнительной информации.