С точки зрения RESTful, я думаю, что совершенно нормально обрабатывать оба представления одинаково.Рассмотрим программное обеспечение с несколькими версиями, которые вы хотите загрузить, последняя из которых 3.8.Так что, если вы хотите получить последнюю версию, вы можете обращаться к ней с GET /software/version/latest.zip
и GET /software/version/3.8.zip
, пока не выйдет более новая версия.Таким образом, две разные ссылки указывают на один и тот же ресурс.
Мне нравится представлять себе нумерацию страниц практически одинаково.На первой странице всегда есть последние статьи.Поэтому, если не указан page
-параметр, вы можете просто предположить, что он равен 1.
Подход с атрибутом rel
идет в несколько ином направлении.Это создание Google, чтобы лучше справляться с проблемой дублирующегося контента, и в первую очередь считается, что оно используется для того, чтобы различать «главную» страницу и страницы пагинации.Вот как это можно использовать:
//first page:
<link rel="next" href="http://www.foo.com/foo?page=2" />
//second page:
<link rel="prev" href="http://www.foo.com/foo?page=1" />
<link rel="next" href="http://www.foo.com/foo?page=3" />
//third and last page:
<link rel="prev" href="http://www.foo.com/foo?page=2" />
Так что с точки зрения SEO это хорошая идея (и рекомендуется Google) использовать эти элементы.Они также прекрасно сочетаются с ориентированной на ресурсы идеей REST и гипермедиа-представлением ресурсов.
Выбрав одно из ваших предложений, я думаю, что 303 See Other
- верный путь.Он был предназначен для использования в подобных целях и является хорошим способом канонизировать ваши ресурсы.Вы можете сделать их доступными через множество URI, но иметь один «реальный» URI для представления (например, программное обеспечение с разными версиями).
Согласно спецификации, ответ должен выглядеть примерно так:
303 See Other
Location: http:www.foo.com/foo?page=1
<a href="http:www.foo.com/foo?page=1">http:www.foo.com/foo?page=1</a>
Таким образом, вы предоставляете Location-заголовок с «реальным» представлением, а тело должно содержать гипертекстовый документ, ссылающийся на новый URI.Обратите внимание, что в соответствии со спецификацией клиент ожидает для отправки запроса GET на значение Location, но он не должен .
// РЕДАКТИРОВАТЬ в качестве ответа на ваш комментарий (да, это действительно плохая практика требовать что-то, не доказывая этого :-) - мой плохой!):
Google представил rel="next"
и rel="prev"
атрибутов в сентябре 2011 года в официальном блоге для веб-мастеров 1034 *.Они могут использоваться дополнительно (или в некоторых случаях вместо) к тегу rel="canonical"
.
. По этим ссылкам вы можете найти различия между ними:
rel="next"
и rel="prev"
элементы ссылки означают "для обозначения взаимосвязи между URL-адресами компонентов в разбитой на страницы серии" - *
rel="canonical"
"позволяет публично указывать предпочитаемый вамиверсия URL "
Так что между ними есть небольшая разница.Таким образом, вы можете разбить вашу проблему на каноническую проблему: есть несколько URL-адресов, указывающих на один и тот же ресурс (/foo
и foo?page=1
, но у вас есть предпочтительная версия URL-адреса (foo?page=1
). Итак, теперь есть несколькоопции для подхода RESTful:
- Если в запросе не указан параметр
page
, используйте значение по умолчанию (например, 1) при его обработке. Я думаю, что в этом конкретном случае это нормальноиспользовать значение по умолчанию, даже если вы указали, что это плохая практика. - Ответьте с помощью 303 См. Другое , предоставив предпочтительный URL-адрес в Местоположение -header (как описано выше). Я думаю, * 3xx -ответ - лучший (и, скорее всего, RESTLY предназначенный) способ работы с дублированным / каноническим контентом.
- Ответьте с помощью 400 Bad Request в случае, если вы хотите заставить клиента предоставить
page
-параметр (как объяснил zzzzBov в своем ответе).Обратите внимание, что этот ответ не имеет что-то вроде заголовка Location (как предполагается в вашем вопросе), поэтому объяснение, почему запрос не удался, и / или правильный URL-адрес (если он указан) долженперейти к объекту-сущности ответа.Также обратите внимание, что в соответствии со спецификацией этот ответ обычно используется, когда клиент отправляет неверное / некорректное представление (! Не URL!) Вместе с запросом PUT
или POST
.Так что имейте в виду, что это также может быть немного двусмысленным для клиента.
Лично я не думаю, что ваше предложение ответить 405 Метод не разрешен хорошая идея.Согласно спецификации, вы должны предоставить Разрешить -заголовок, перечисляющий разрешенные методы.Но какие методы могут быть разрешены на этом ресурсе?Я могу думать только о POST
.Но если вы не хотите, чтобы клиент также POST
ему, вы также можете ответить 403 Forbidden с объяснением, почему это запрещено, или 404 Не найдено , если вы не хотите сказать, почему это запрещено.Так что это может быть немного двусмысленно (на мой взгляд).
Использование link
-элементов с упомянутыми rel
-атрибутами, как вы предлагаете в своем вопросе, по сути не является "RESTful", потому чтогипермедиа, которая решается в представлении ресурса.Но ваша проблема (насколько я понимаю) состоит в том, что вы хотите решить, как ответить на конкретный запрос и какое представление обслуживать.Но все же это не совсем бессмысленно:
Вы можете рассматривать всю проблему SEO как побочный эффект использования rel="next/prev/canonical"
, но имейте в виду, что они также создают связность (как качествоналичие ссылок), что является одной из характеристик REST (см. диссертацию Роя Филдинга ).
Если вы хотите погрузиться в RESTful Web Services (что того стоит), я рекомендую прочитатькнига RESTful Web Services Леонарда Ричардсона и Сэма Руби.