Разбиение на страницы полезная нагрузка ответ от API с поддержкой REST
Я хочу поддерживать разбиение на страницы в моем RESTful API.
мой метод API должен возвращать список JSON продукта через /products/index
. Тем не менее, есть потенциально тысячи продуктов, и я хочу пролистать их, поэтому мой запрос должен выглядеть примерно так:
/products/index?page_number=5&page_size=20
но как должен выглядеть мой ответ JSON? Будут ли потребители API обычно ожидать метаданных разбиения на страницы в ответе? Или только массив продуктов необходим? Зачем?
это похоже, что API Twitter включает в себя метаданные:https://dev.twitter.com/docs/api/1/get/lists/members (см. пример запроса).
с метаданными:
{
"page_number": 5,
"page_size": 20,
"total_record_count": 521,
"records": [
{
"id": 1,
"name": "Widget #1"
},
{
"id": 2,
"name": "Widget #2"
},
{
"id": 3,
"name": "Widget #3"
}
]
}
просто массив продуктов (без метаданных):
[
{
"id": 1,
"name": "Widget #1"
},
{
"id": 2,
"name": "Widget #2"
},
{
"id": 3,
"name": "Widget #3"
}
]
3 ответа:
RESTful API используются в основном другими системами, поэтому я помещаю данные подкачки в заголовки ответов. Однако некоторые потребители API могут не иметь прямого доступа к заголовкам ответов или могут создавать UX над вашим API, поэтому предоставление способа получения (по требованию) метаданных в ответе JSON является плюсом.
Я считаю, что ваша реализация должна включать машиночитаемые метаданные по умолчанию и читаемые человеком метаданные при запросе. Человек-читаемый метаданные могут быть возвращены с каждым запросом, если вы хотите или, предпочтительно, по требованию с помощью параметра запроса, такого как
include=metadata
илиinclude_metadata=true
.в вашем конкретном случае, я бы включил URI для каждого продукта с записью. Это упрощает для потребителя API создание ссылок на отдельные продукты. Я бы также установил некоторые разумные ожидания в соответствии с пределами моих запросов на пейджинг. Реализация и документирование параметров по умолчанию для размера страницы является приемлемым практиковать. Например, API GitHub устанавливает размер страницы по умолчанию в 30 записей с максимумом 100, а также устанавливает ограничение скорости на количество раз, когда вы можете запросить API. Если ваш API имеет размер страницы по умолчанию, то строка запроса может просто указать индекс страницы.
в удобочитаемом сценарии при переходе к
/products?page=5&per_page=20&include=metadata
, ответ может быть:{ "_metadata": { "page": 5, "per_page": 20, "page_count": 20, "total_count": 521, "Links": [ {"self": "/products?page=5&per_page=20"}, {"first": "/products?page=0&per_page=20"}, {"previous": "/products?page=4&per_page=20"}, {"next": "/products?page=6&per_page=20"}, {"last": "/products?page=26&per_page=20"}, ] }, "records": [ { "id": 1, "name": "Widget #1", "uri": "/products/1" }, { "id": 2, "name": "Widget #2", "uri": "/products/2" }, { "id": 3, "name": "Widget #3", "uri": "/products/3" } ] }
для машиночитаемых метаданных я бы добавил заголовки ссылке к ответ:
Link: </products?page=5&perPage=20>;rel=self,</products?page=0&perPage=20>;rel=first,</products?page=4&perPage=20>;rel=previous,</products?page=6&perPage=20>;rel=next,</products?page=26&perPage=20>;rel=last
(значение заголовка ссылки должно быть urlencoded)
...и, возможно, обычай
total-count
заголовок ответа, если вы так выбираете:total-count: 521
другие данные подкачки, обнаруженные в человеко-ориентированных метаданных, могут быть излишними для машинно-ориентированных метаданных, поскольку заголовки ссылок позволяют мне знать, на какой странице Я нахожусь, и число на странице, и я могу быстро получить количество записей в массиве. Поэтому, я бы, наверное, только создайте заголовок для общего количества. Вы всегда можете изменить свое решение позже и добавить больше метаданных.
в сторону, вы можете заметить, что я удалил
/index
из вашего URI. Общепринятое соглашение заключается в том, чтобы ваша конечная точка ReST предоставляла коллекции. Имея/index
в конце мутит, что слегка.это всего лишь несколько вещей, которые я хотел бы иметь при потреблении / создании API. Надеюсь, это поможет!
Как кто-то, кто написал несколько библиотек для использования служб REST, позвольте мне дать вам точку зрения клиента на то, почему я думаю, что обертывание результата в метаданные-это путь:
- без общего количества, как клиент может знать, что он еще не получил все, что есть, и должен продолжать листать через результирующий набор? В пользовательский интерфейс, который не смотрит вперед на следующую страницу, в худшем случае это может быть представлено следующим более/ссылка, которая не на самом деле получить больше данных.
- включение метаданных в ответ позволяет клиенту отслеживать меньше состояния. Теперь мне не нужно сопоставлять мой запрос REST с ответом, поскольку ответ содержит метаданные, необходимые для восстановления состояния запроса (в этом случае курсор в набор данных).
- Если состояние является частью ответа, я могу одновременно выполнять несколько запросов в один и тот же набор данных, и я могу обрабатывать запросы в любом порядке, в котором они поступают в котором не обязательно порядок, в котором я сделал запросы.
и предложение: как Twitter API, вы должны заменить page_number прямым индексом / курсором. Причина в том, что API позволяет клиенту установить размер страницы для каждого запроса. Является ли возвращаемый page_number количеством страниц, которые клиент запросил до сих пор, или номером страницы, заданным последним используемым page_size (почти наверняка более поздним, но почему бы не избежать такой двусмысленности вообще)?
Я бы рекомендовал добавить заголовки для того же. Перемещение метаданных в заголовки помогает избавиться от оболочек, таких как
result
,data
илиrecords
и тело ответа содержит только необходимые нам данные. Вы можете использовать ссылке заголовок, если вы создаете ссылки на страницы тоже.HTTP/1.1 200 Pagination-Count: 100 Pagination-Page: 5 Pagination-Limit: 20 Content-Type: application/json [ { "id": 10, "name": "shirt", "color": "red", "price": "" }, { "id": 11, "name": "shirt", "color": "blue", "price": "" } ]
Подробнее см.:
https://github.com/adnan-kamili/rest-api-response-format
для чванства файл: