В последнее время я проводил обширные исследования этого и других вопросов, связанных с поиском по REST, и счел целесообразным добавить некоторые из моих выводов здесь. Я немного расширил вопрос, включив в него мысли о подкачке страниц, а также подсчет, поскольку они очень тесно связаны.
Заголовки
Метаданные подкачки включены в ответ в виде заголовков ответа. Большим преимуществом этого подхода является то, что сама полезная нагрузка ответа - это именно то, о чем запрашивал сам запросчик данных. Облегчение обработки ответа для клиентов, которые не заинтересованы в информации подкачки.
Существует несколько (стандартных и пользовательских) заголовков, используемых в wild для возврата информации, относящейся к подкачке, включая общее количество.
X-Total-Count
X-Total-Count: 234
Используется в некоторых API , которые я нашел в дикой природе. Есть также пакеты NPM для добавления поддержки этого заголовка, например. Loopback. Некоторые статьи рекомендуют также установить этот заголовок.
Часто используется в сочетании с заголовком Link
, который является довольно хорошим решением для подкачки, но в нем отсутствует информация об общем количестве.
Ссылка
Link: </TheBook/chapter2>;
rel="previous"; title*=UTF-8'de'letztes%20Kapitel,
</TheBook/chapter4>;
rel="next"; title*=UTF-8'de'n%c3%a4chstes%20Kapitel
Из прочтения этой темы я чувствую, что общий консенсус заключается в использовании Link
заголовка для предоставления пейджинговых ссылок клиентам, использующим rel=next
, rel=previous
и т. Д. Проблема Это связано с тем, что ему не хватает информации о количестве записей, поэтому многие API сочетают это с заголовком X-Total-Count
.
В качестве альтернативы, некоторые API и, например, стандарт JsonApi , используйте формат Link
, но добавляйте информацию в конверте ответа, а не в заголовок. Это упрощает доступ к метаданным (и создает место для добавления информации об общем количестве) за счет усложнения доступа к самим фактическим данным (путем добавления конверта).
Content-Range
Content-Range: items 0-49/234
Продвигается статья блога с именем Заголовок диапазона, я выбираю вас (для нумерации страниц)! . Автор приводит веские аргументы в пользу использования заголовков Range
и Content-Range
для нумерации страниц. Когда мы внимательно прочитаем RFC на этих заголовках, мы обнаружим, что расширение их значения за пределы диапазонов байтов фактически ожидалось RFC и явно разрешено. При использовании в контексте items
вместо bytes
заголовок Range фактически дает нам возможность как запросить определенный диапазон элементов, так и указать, к какому диапазону общего результата относятся элементы ответа. Этот заголовок также дает отличный способ показать общее количество. И это настоящий стандарт, который в основном отображает один на один на пейджинг. Это также используется в дикой природе .
Конверт
Многие API, включая от нашего любимого сайта вопросов и ответов , используют конверт , обертку вокруг данных, которая используется для добавления метаинформации о данных. Кроме того, стандарты OData и JsonApi используют конверт ответа.
Большим недостатком этого (imho) является то, что обработка данных ответа становится более сложной, поскольку реальные данные должны быть найдены где-то в конверте. Также есть много разных форматов для этого конверта, и вы должны использовать правильный. Это говорит о том, что конверты ответа от OData и JsonApi сильно отличаются друг от друга, причем OData смешивает метаданные в нескольких точках ответа.
Отдельная конечная точка
Я думаю, что это было достаточно освещено в других ответах. Я не исследовал это много, потому что я согласен с комментариями, что это сбивает с толку, поскольку у вас сейчас есть несколько типов конечных точек. Я думаю, что было бы лучше, если бы каждая конечная точка представляла (коллекцию) ресурс (ы).
Дальнейшие мысли
Мы должны не только сообщать метаинформацию подкачки, связанную с ответом, но и позволять клиенту запрашивать определенные страницы / диапазоны. Интересно также взглянуть на этот аспект, чтобы получить согласованное решение. Здесь также мы можем использовать заголовки (заголовок Range
кажется очень подходящим) или другие механизмы, такие как параметры запроса. Некоторые люди рекомендуют рассматривать страницы результатов как отдельные ресурсы, что может иметь смысл в некоторых случаях использования (например, /books/231/pages/52
. В итоге я выбрал широкий диапазон часто используемых параметров запроса, таких как pagesize
, page[size]
и limit
и т.д. в дополнение к поддержке заголовка Range
(и в качестве параметра запроса).