Почему заголовок местоположения HTTP устанавливается только для запросов POST/201 (создано) ответов?

На мгновение игнорируя ответы 3xx, мне интересно, почему заголовок местоположения HTTP используется только в сочетании с ответами POST-запросов/201 (Created).

Из спецификации RFC 2616:

Для ответов 201 (Создано) Location соответствует местоположению нового ресурса, который был создан по запросу.

Это широко поддерживаемое поведение, но почему бы его не использовать с другими методами HTTP? В качестве примера возьмем спецификацию JSON API:

Он определяет ссылку на себя для текущего ресурса внутри полезной нагрузки JSON (не редкость для RESTful API). Эта ссылка включена в каждую полезную нагрузку. В спецификации говорится, что вы ДОЛЖНЫ включать заголовок местоположения HTTP, если вы создаете новый документ с помощью POST, и что значение совпадает со ссылкой на саму себя в полезной нагрузке, но это ТОЛЬКО ТОЛЬКО требуется для POST. Зачем возиться с настраиваемым форматом ссылки на себя, если можно просто использовать HTTP-заголовок местоположения?

Примечание. Это не относится к JSON API. То же самое для HAL, Гиперсхема JSON или другие стандарты.

Примечание 2. Это даже не относится к заголовку местоположения HTTP, поскольку оно совпадает с заголовком ссылки HTTP. Как видите, JSON API, HAL и гиперсхема JSON не только определяют соглашения для ссылок на самих себя, но и для выражения информации о связанных ресурсах или возможных действиях для ресурса. Но кажется, что все они могли просто использовать заголовок ссылки HTTP. (Они могли бы даже поместить ссылку на себя в заголовок ссылки HTTP, если они не хотят использовать заголовок местоположения HTTP.)

Я не хочу разглагольствовать, это просто похоже на "изобретение велосипеда". Это также кажется очень ограничивающим: если вы просто используете HTTP-заголовок местоположения/ссылки, не имеет значения, запрашиваете ли вы JSON, XML или что-то еще в своем HTTP-заголовке принятия, и вы получите полезную метаинформацию о своем ресурсе на запрос HEAD, который не будет содержать ссылки, если вы будете использовать JSON API, HAL или JSON Hyper-Schema.


person Pipo    schedule 04.06.2014    source источник


Ответы (2)


Семантика заголовка Location — это не ссылка на себя, а ссылка, которой должен следовать пользовательский агент, чтобы выполнить запрос. Это имеет смысл в перенаправлениях, и когда вы создаете новый ресурс, который будет находиться в новом месте, куда вы должны перейти. Если ваш запрос уже выполнен, то есть у вас уже есть полное представление о ресурсе, который вы хотели, нет смысла возвращать Location.

Заголовок Link может считаться семантически эквивалентным гипертекстовой ссылке, но его следует использовать для ссылки на метаданные, относящиеся к данному ресурсу, когда медиа-тип не поддерживает гипермедиа, поэтому он не заменяет функциональность ссылки на связанный ресурс. ресурсы в RESTful API.

Необходимость в пользовательском формате ссылки в представлении ресурса связана с необходимостью отделить ресурс от базовой реализации и протокола. REST не связан с HTTP, и можно использовать любой протокол, для которого существует допустимая схема URI. Если вы решили использовать заголовок Link для всех ссылок, вы подключаетесь к HTTP.

Допустим, вы предоставляете клиентам FTP-ссылку. Где в таком случае будет Link?

person Pedro Werneck    schedule 04.06.2014
comment
REST не связан с HTTP, и можно использовать любой протокол, для которого существует допустимая схема URI. [...] Если вы решили использовать заголовок Link для всех ссылок, вы подключаетесь к HTTP. Я думаю, что этот пункт является наиболее последовательным для меня. - person Pipo; 05.06.2014
comment
Извините, подумав еще раз, я думаю, что не понимаю... Заголовок Link следует использовать для ссылки на метаданные, относящиеся к данному ресурсу. Звучит так же, как функциональность ссылки на связанные ресурсы в RESTful API? REST не связан с HTTP... Возможно. Но если бы это было проблемой, разве мне не нужно было бы также раскрывать мои HTTP-методы в моей полезной нагрузке? Например. /users/123/удалить или /users/123/поставить? Мои DELETE и PUT зависят от HTTP... почему не должны мои ссылки? - person Pipo; 05.06.2014
comment
Но как еще один контраргумент: должен ли я относиться к своим документам JSON для машин так же, как к моим документам HTML для людей...? Я бы не спрашивал, должен ли я переместить ссылки и кнопки из моего HTML в заголовок HTTP... - person Pipo; 05.06.2014
comment
Да, в этом смысле вы можете сказать, что заголовок ссылки семантически эквивалентен ссылкам в полезной нагрузке, и некоторые люди защищают реализацию HATEOAS только с заголовком Link. Я думаю, что это должно быть зарезервировано только для медиа-типов, которые не поддерживают гипермедиа. Просто подумайте, что REST — это архитектурный стиль, основанный на успешных дизайнерских решениях, принятых для самой сети. REST API должен быть доступным для навигации и обнаружения точно так же, как веб-сайт. Вы обычно проверяете ссылки в заголовках HTTP, когда просматриваете веб-страницу? - person Pedro Werneck; 05.06.2014
comment
Если вы не обрабатываете свои документы JSON так же, как HTML для людей, то есть они не поддерживают гипермедиа, то вы не используете REST. Вы должны использовать заголовок Link, когда вам нужно предоставить ссылки для типа мультимедиа, который не поддерживает гипермедиа. Например, вы хотите указать автора изображения. Вы не можете вставить ссылку в само изображение. Рекомендуемое чтение: roy.gbiv.com/untangled/2008 /rest-apis-must-be-hypertext-driven - person Pedro Werneck; 05.06.2014
comment
Что касается методов в ваших гипермедиа-документах, это обсуждение появилось недавно. Вы также можете проверить эту группу. groups.google.com/forum/#!topic/api-craft/ v0GNu7ksO3s - person Pedro Werneck; 05.06.2014
comment
Большое спасибо за ваши усилия. Я посмотрю вашу последнюю ссылку. (Статью знаю по первой ссылке, но она очень теоретическая. Я говорю делать гипертекст, но не как именно.) - person Pipo; 05.06.2014
comment
В том, как это сделать, нет никакой тайны: так работает любой веб-сайт. Обычно это не так очевидно, потому что большинство API используют такой формат, как JSON, без собственного синтаксиса для гиперссылок. Проверьте hal+json, это должно дать вам идеи. stateless.co/hal_specification.html - person Pedro Werneck; 05.06.2014
comment
Думаю, это небольшая загадка. Если бы это было очевидно, у нас не было бы столько спецификаций, делающих все по-другому :) hal+json — это всего лишь один из способов сделать это. Еще раз спасибо за ваш ответ. - person Pipo; 06.06.2014

Семантика заголовка Location зависит от кода состояния. Для 201 он ссылается на вновь созданный ресурс, но в запросах 3xx может иметь несколько (хотя и схожих) значений. Я думаю, именно поэтому его обычно избегают для других целей.

Альтернативой является заголовок Content-Location, который всегда имеет непротиворечивое значение. Он сообщает клиенту канонический URL-адрес запрошенного им ресурса. Он является чисто информативным (в отличие от Location, который должен обрабатываться клиентом).

Таким образом, заголовок Content-Location кажется более похожим на ссылку на себя. Однако Content-Location также не имеет определенного поведение для PUT и POST. Это также, кажется, довольно редко используется.

Этот пост в блоге местоположение и содержание-местоположение хорошее сравнение. Вот цитата:

Наконец, ни один из заголовков не предназначен для связывания общего назначения.

В общем, кажется хорошей идеей требовать стандартизированную самостоятельную связь в теле. Это позволяет избежать путаницы на стороне клиента.

person Philipp Claßen    schedule 04.06.2014