HTTP Response 412 - можете ли вы включить контент?
Я строю хранилище данных RESTful и использую условные GET и PUT. Во время условного PUT клиент может включить Etag из предыдущего GET на ресурс, и если текущее представление не соответствует, сервер вернет код состояния HTTP 412 (Precondition Failed). Обратите внимание, что это сервер / протокол на основе Atom.
У меня вопрос, когда я возвращаю статус 412, могу ли я также включить новое представление ресурса или должен ли пользователь выдать новый GET? Спецификация HTTP, кажется, не говорит да или нет, а также спецификация Atom (хотя их пример показывает пустое тело сущности в ответе). Кажется довольно расточительным не возвращать новое представление и не заставлять клиента специально ПОЛУЧИТЬ его. Мысли?
3 ответа
Хотя условные GET и PUT суммируются как "условные запросы", они концептуально сильно различаются. Условные GET - это оптимизация производительности, а условные PUT - механизм управления параллелизмом. Трудно обсуждать их вместе.
На ваш вопрос об условном GET: если вы отправите GET и включите заголовок If-None-Match, сервер отправит 200 Ok, если ресурс изменился, и 304 Not Modified, если этого не произошло (если условие не выполнено). 412 должен использоваться только с условными PUT.
ОБНОВЛЕНИЕ: Кажется, я немного неправильно понял вопрос. К вашему сведению относительно "обновления" локальной копии после сбоя условного PUT: вполне возможно, что кеш уже имеет самую новую версию и что ваш refresh-GET будет обслуживаться из некоторого кеша. Если сервер вернет текущую сущность с 412, это может привести к ухудшению производительности.
Нет, технически не стоит. Коды ошибок обычно указывают, что что-то пошло не так. Хотя ничто не помешает вам вернуть контент (и на самом деле, некоторые ошибки, такие как 404, возвращают симпатичную страницу, которая говорит, что вы не нашли то, что искали), смысл ответа не в том, чтобы вернуть другой контент, но чтобы вернуть то, что говорит вам, что было не так. Технически вы также не должны возвращать эти данные, потому что вы передали If-None-Match: etag (я предполагаю, что вы это передали?)
С другой стороны, вам действительно нужно оптимизировать еще один HTTP-вызов?
Чем больше я думаю об этом, тем больше я убежден, что это плохая идея. Собираетесь ли вы возвращать контент при любых других ошибках? Семантика PUT относится к PUT. Семантика GET должна использоваться для GET.
Если количество дополнительных запросов, вызванных дополнительным запросом после конфликта обновления, является достаточно значительным для того, чтобы у вас возникли проблемы с производительностью, я бы предположил, что у вас могут возникнуть проблемы с гранулярностью ваших ресурсов.
Вы действительно ожидаете, что миллионы раз в день несколько пользователей будут одновременно редактировать один и тот же ресурс? Возможно, вам нужно хранить дельта-изменения в ресурсе, а не обновлять ресурс напрямую. Если за эти ресурсы действительно много споров, то не будут ли пользователи постоянно работать над устаревшими данными.
Если ваша проблема заключалась в том, что ваш ресурс содержит дату последнего изменения и пользователя последнего изменения и вам приходилось делать GET после каждого PUT, я бы больше убеждался в необходимости искажать правила.
Тем не менее, я думаю, что снижение производительности дополнительного запроса того стоит для ясности для разработчика клиента.