Это более общая переформулировка этого вопроса (с устранением отдельных частей Rails)
Я не уверен, как реализовать разбиение на страницы для ресурса в веб-приложении RESTful. Предполагая, что у меня есть ресурс под названием products
, какой из следующих вариантов вы считаете лучшим и почему:
1. Использование только строк запроса
например. http://application/products?page=2&sort_by=date&sort_how=asc
Проблема здесь в том, что я не могу использовать полное кэширование страниц, а также URL-адрес не очень чистый и его легко запомнить.
2. Использование страниц в качестве ресурсов и строк запросов для сортировки
например. http://application/products/page/2?sort_by=date&sort_how=asc
В этом случае проблема заключается в том, что http://application/products/pages/1
это не уникальный ресурс, поскольку использование sort_by=price
может дать совершенно другой результат, и я все еще не могу использовать кэширование страниц.
3. Использование страниц в качестве ресурсов и сегмента URL для сортировки
например. http://application/products/by-date/page/2
Я лично не вижу проблем в использовании этого метода, но кто-то предупредил меня, что это не очень хороший способ (он не привел причину, поэтому, если вы знаете, почему это не рекомендуется, пожалуйста, дайте мне знать)
Любые предложения, мнения, критика приветствуются. Спасибо.
Ответы:
Я думаю, что проблема с версией 3 - это скорее проблема «точки зрения» - вы видите страницу как ресурс или продукты на странице.
Если вы видите страницу как ресурс, то это идеальное решение, так как запрос для страницы 2 всегда будет давать страницу 2.
Но если вы видите продукты на странице как ресурс, у вас есть проблема, связанная с тем, что продукты на странице 2 могут измениться (старые продукты удалены или что-то еще), в этом случае URI не всегда возвращает один и тот же ресурс (ы).
Например, клиент сохраняет ссылку на страницу со списком продуктов X, и в следующий раз, когда ссылка будет открыта, рассматриваемый продукт может больше не отображаться на странице X.
источник
Я согласен с Fionn, но я сделаю еще один шаг и скажу, что для меня страница не является ресурсом, это свойство запроса. Это заставляет меня выбирать только строку запроса варианта 1. Это просто чувствует себя хорошо. Мне действительно нравится, как Twitter API структурирован спокойно. Не слишком просто, не слишком сложно, хорошо документировано. Что бы там ни было, это мой дизайн «идти к», когда я стою на пороге, делая что-то одно против другого.
источник
HTTP имеет отличный заголовок Range, который также подходит для нумерации страниц. Вы можете отправить
иметь только первую страницу. Это может заставить вас переосмыслить, что такое страница. Возможно, клиент хочет другой ассортимент товаров. Заголовок диапазона также работает, чтобы объявить заказ:
чтобы все продукты были новее этой даты или
чтобы получить все продукты старше этой даты. «0», вероятно, не лучшее решение, но RFC, похоже, хочет что-то для начала диапазона. Могут быть развернуты парсеры HTTP, которые не будут анализировать единицы = -range_end.
Если заголовки не являются (приемлемым) вариантом, я считаю, что первое решение (все в строке запроса) - это способ работы со страницами. Но, пожалуйста, нормализуйте строки запроса (сортируйте (ключ = значение) пары в алфавитном порядке). Это решает проблему дифференциации «? A = 1 & b = x» и «? B = x & a = 1».
источник
range-unit = bytes-unit | other-range-unit
Может быть, вы имеете в виду,The only range unit defined by HTTP/1.1 is "bytes". HTTP/1.1 implementations MAY ignore ranges specified using other units.
что это не то же самое, что ваше заявление.Вариант 1 кажется наилучшим в той степени, в которой ваше приложение рассматривает разбиение на страницы как метод создания другого представления одного и того же ресурса.
Сказав это, схема URL является относительно незначительным. Если вы разрабатываете свое приложение на основе гипертекста (как все приложения REST должны быть по определению), тогда ваш клиент не будет создавать какие-либо URI самостоятельно. Вместо этого ваше приложение будет давать ссылки клиенту, а клиент будет следовать за ними.
Один из видов ссылок, которые может предоставить ваш клиент, - это ссылка на страницы.
Приятным побочным эффектом всего этого является то, что даже если вы передумаете по поводу структуры URI-страниц и внедрите что-то совершенно другое на следующей неделе, ваши клиенты могут продолжать работать без каких-либо изменений.
источник
Я всегда использовал стиль варианта 1. Кэширование не было проблемой, так как в любом случае данные часто меняются. Если вы позволяете настраивать размер страницы, данные снова не могут быть кэшированы.
Я не считаю URL запоминающимся или нечистым. Для меня это хорошее использование параметров запроса. Ресурс представляет собой список продуктов, а параметры запроса просто указывают, как вы хотите, чтобы список отображался - сортировался и на какой странице.
источник
Странно, что никто не указал, что вариант 3 имеет параметры в определенном порядке. http // application / products / Date / Descending / Name / Ascending / page / 2 и http // application / products / Name / Ascending / Date / Descending / page / 2
указывают на один и тот же ресурс, но имеют совершенно разные URL.
Для меня вариант 1 кажется наиболее приемлемым, поскольку он четко разделяет слова «Что я хочу» и «Как я хочу» (между ними даже есть знак вопроса). Кеширование на всю страницу может быть реализовано с использованием полного URL-адреса (в любом случае все параметры будут иметь одну и ту же проблему).
При подходе «Параметры в URL» единственным преимуществом является чистый URL. Хотя вы должны придумать какой-то способ кодирования параметров и декодирования без потерь. Конечно, вы можете пойти с URLencode / decode, но это снова сделает URL ужасными :)
источник
Я бы предпочел использовать параметры запроса offset и limit.
смещение : для индекса элемента в коллекции.
предел : для подсчета предметов.
Клиент может просто обновлять смещение следующим образом
для следующей страницы.
Путь считается идентификатором ресурса. И страница не ресурс, а подмножество коллекции ресурсов. Поскольку разбиение на страницы обычно является запросом GET, параметры запроса лучше всего подходят для разбиения на страницы, а не для заголовков.
Ссылка: https://metamug.com/article/rest-api-developers-dilemma.html#Requesting-the-next-page
источник
В поисках лучших практик я наткнулся на этот сайт:
http://www.restapitutorial.com
На странице ресурсов есть ссылка для загрузки .pdf, содержащего полные рекомендации REST, предложенные автором. В котором среди прочего есть раздел о нумерации страниц.
Автор предлагает добавить поддержку как при использовании заголовка Range, так и при использовании параметров строки запроса.
Запрос
Пример заголовка HTTP:
Пример параметров строки запроса:
Где смещение - это номер начального элемента, а ограничение - максимальное количество элементов для возврата.
отклик
Ответ должен включать заголовок Content-Range, указывающий, сколько элементов возвращается и сколько всего элементов еще предстоит получить.
Примеры заголовков HTTP:
В .pdf есть некоторые другие предложения для более конкретных случаев.
источник
В настоящее время я использую схему, подобную этой в моих приложениях ASP.NET MVC:
например
http://application/products/by-date/page/2
конкретно это:
http://application/products/Date/Ascending/3
Тем не менее, я не очень доволен включением подкачки и сортировки информации в маршрут таким образом.
Список товаров (в данном случае товары) является изменчивым. т. е. в следующий раз, когда кто-то вернется к URL-адресу, который включает параметры подкачки и сортировки, полученные результаты могут измениться. Таким образом, идея
http://application/products/Date/Ascending/3
уникального URL-адреса, который указывает на определенный, неизменный набор продуктов, теряется.источник
Я склонен согласиться с slf, что «страница» на самом деле не ресурс. С другой стороны, вариант 3 чище, проще для чтения и может быть легче угадан пользователем и даже напечатан при необходимости. Я разрываюсь между вариантами 1 и 3, но не вижу причин не использовать вариант 3.
Кроме того, хотя они выглядят хорошо, одним из недостатков использования скрытых параметров, как кто-то упоминал, а не строк запроса или сегментов URL-адресов, является то, что пользователь не может делать закладки или напрямую ссылаться на определенную страницу. Это может или не может быть проблемой в зависимости от приложения, но просто кое-что, чтобы знать.
источник
Я использовал решение 3 раньше (я пишу много приложений Django). И я не думаю, что с этим что-то не так. Он так же генерируемый, как и два других (в случае, если вам нужно сделать несколько операций по очистке или тому подобное), и выглядит чище. Кроме того, ваши пользователи могут угадывать URL-адреса (если это общедоступное приложение), и людям нравится иметь возможность идти прямо туда, куда они хотят, а угадывание URL-адресов дает им возможность.
источник
Я использую в своих проектах следующие URL:
что означает - «дай мне страницу вторую страницу, упорядоченную по возрастанию по field1 и затем по убыванию по field2». Или, если мне нужна еще большая гибкость, я использую:
источник
Я использую в следующих шаблонах, чтобы получить следующую страницу записи. HTTP: //? приложение / продукты lastRecordKey = & PAGESIZE = 20 & сортировки = ASC
RecordKey - это столбец таблицы, который содержит последовательное значение в БД. Это используется для получения только одной страницы данных за один раз из БД. pageSize используется для определения количества записей для выборки. sort используется для сортировки записи в порядке возрастания или убывания.
источник