Пагинация в веб-приложении REST - PullRequest
321 голосов
/ 22 апреля 2009

Это более общая переформулировка этого вопроса (с исключением специфических частей 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
Я лично не вижу проблем в использовании этого метода, но кто-то предупредил меня, что это не очень хороший способ (он не назвал причину, поэтому, если вы знаете , почему , это не рекомендуется пожалуйста, дайте мне знать)

Любые предложения, мнения, критика приветствуются. Спасибо.

Ответы [ 12 ]

103 голосов
/ 22 апреля 2009

Я согласен с Fionn, но я сделаю еще один шаг и скажу, что для меня страница является , а не ресурсом, это свойство запроса. Это заставляет меня выбирать только строку запроса варианта 1. Это просто чувствует себя хорошо. Мне очень нравится, как Twitter API структурирован спокойно. Не слишком просто, не слишком сложно, хорошо документировано. Что бы там ни было, это мой дизайн «перейти к», когда я стою на пороге, делая что-то одно против другого.

62 голосов
/ 22 апреля 2009

Я думаю, что проблема с версией 3 - это скорее проблема «точки зрения» - вы видите страницу как ресурс или продукты на странице.

Если вы видите страницу как ресурс, это идеальное решение, так как запрос для страницы 2 всегда будет давать страницу 2.

Но если вы видите продукты на странице как ресурс, у вас есть проблема, что продукты на странице 2 могут измениться (старые продукты удалены или что-то в этом роде), в этом случае URI не всегда возвращая тот же ресурс (ы).

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

35 голосов
/ 04 декабря 2009

HTTP имеет отличный заголовок Range, который также подходит для нумерации страниц. Вы можете отправить

Range: pages=1

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

Range: products-by-date=2009_03_27-

чтобы получить все продукты новее этой даты или

Range: products-by-date=0-2009_11_30

чтобы получить все товары старше этой даты. «0», вероятно, не лучшее решение, но RFC, похоже, хочет что-то для начала диапазона. Могут быть развернуты парсеры HTTP, которые не будут анализировать единицы = -range_end.

Если заголовки не являются (приемлемым) вариантом, я считаю, что первое решение (все в строке запроса) - это способ работы со страницами. Но, пожалуйста, нормализуйте строки запроса (сортируйте пары (ключ = значение) в алфавитном порядке). Это решает проблему дифференциации «? A = 1 & b = x» и «? B = x & a = 1».

24 голосов
/ 26 июля 2009

Вариант 1 кажется наилучшим, если ваше приложение рассматривает разбиение на страницы как метод создания другого представления одного и того же ресурса.

Сказав это, схема URL относительно незначительна. Если вы разрабатываете свое приложение как управляемое гипертекстом (поскольку все приложения REST должны быть по определению), тогда ваш клиент не будет создавать какие-либо URI самостоятельно. Вместо этого ваше приложение будет давать ссылки клиенту, а клиент будет следовать за ними.

Один из видов ссылок, которые может предоставить ваш клиент, - это ссылка на нумерацию страниц.

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

11 голосов
/ 04 мая 2009

Я всегда использовал стиль варианта 1. Кэширование не было проблемой, так как в любом случае данные часто меняются. Если вы разрешите настройку размера страницы, данные снова не будут кэшироваться.

Я не нахожу этот URL запоминающимся или нечистым. Для меня это хорошее использование параметров запроса. Ресурс представляет собой список продуктов, а параметры запроса просто указывают, как вы хотите, чтобы список отображался - сортировался и на какой странице.

8 голосов
/ 17 марта 2010

Странно, что никто не указал, что у Варианта 3 есть параметры в определенном порядке. HTTP // приложение / Продукты / Дата / по убыванию / Имя / по возрастанию / страница / 2 а также HTTP // приложение / Продукты / Имя / по возрастанию / Дата / по убыванию / страница / 2

указывают на один и тот же ресурс, но имеют совершенно разные URL.

Для меня вариант 1 кажется наиболее приемлемым, поскольку он четко разделяет «Что я хочу» и «Как я хочу» это (даже между ними есть вопросительный знак) , Кэширование на всю страницу может быть реализовано с использованием полного URL-адреса (в любом случае все параметры будут иметь одну и ту же проблему).

При подходе «Параметры в URL» единственным преимуществом является чистый URL. Хотя вам нужно придумать какой-то способ для кодирования параметров и их декодирования без потерь. Конечно, вы можете использовать URLencode / decode, но это снова сделает URL ужасными:)

6 голосов
/ 23 июля 2015

Я бы предпочел использовать параметры запроса offset и limit.

смещение : для индекса элемента в коллекции.

предел : для подсчета предметов.

Клиент может просто обновлять смещение следующим образом

offset = offset + limit

для следующей страницы.

Путь считается идентификатором ресурса. И страница не ресурс, а подмножество коллекции ресурсов. Поскольку разбиение на страницы обычно является запросом GET, параметры запроса лучше всего подходят для разбиения на страницы, а не для заголовков.

Я использую metamug . У них это настраивается. Пагинация в метамуге запроса select

4 голосов
/ 22 апреля 2009

В настоящее время я использую схему, подобную этой, в моих приложениях ASP.NET MVC:

например. http://application/products/by-date/page/2

конкретно это: http://application/products/Date/Ascending/3

Тем не менее, я не очень доволен включением в маршрут подкачки и сортировки информации таким способом.

Список товаров (в данном случае товары) является изменяемым. то есть в следующий раз, когда кто-то вернется к URL-адресу, который включает параметры подкачки и сортировки, полученные результаты могут измениться. Таким образом, идея http://application/products/Date/Ascending/3 как уникального URL, который указывает на определенный, неизменный набор продуктов, теряется.

3 голосов
/ 08 марта 2016

В поисках лучших практик я наткнулся на этот сайт:

http://www.restapitutorial.com

На странице ресурсов есть ссылка для загрузки .pdf, содержащего полные рекомендации REST, предложенные автором. В котором среди прочего есть раздел о нумерации страниц.

Автор предлагает добавить поддержку как для заголовка Range, так и для параметров строки запроса.

Запрос

Пример заголовка HTTP:

Range: items=0-24

Пример параметров строки запроса:

GET http://api.example.com/resources?offset=0&limit=25

Где смещение - это номер начального элемента, а limit - максимальное количество возвращаемых элементов.

Ответ

Ответ должен содержать заголовок Content-Range, указывающий, сколько элементов возвращается и сколько всего элементов еще предстоит получить

Примеры заголовков HTTP:

Content-Range: items 0-24/66

Content-Range: items 40-65/*

В .pdf есть некоторые другие предложения для более конкретных случаев.

1 голос
/ 22 апреля 2009

Я склонен согласиться с slf, что «страница» на самом деле не ресурс. С другой стороны, вариант 3 чище, его легче читать, и он может быть легче угадан пользователем и даже напечатан при необходимости. Я разрываюсь между вариантами 1 и 3, но не вижу причин, чтобы не использовать вариант 3.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...