Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як віддати пагіновану колекцію через API Resource і що буде у відповіді?

Якщо передати в колекцію ресурсів пагінатор, Laravel додає до відповіді посилання й метадані пагінації:

public function index(Request $request)
{
    $posts = Post::query()
        ->with('author')
        ->latest()
        ->paginate(perPage: min((int) $request->integer('per_page', 20), 100));

    return PostResource::collection($posts);
}
{
  "data": [ { "id": 41, "title": "..." } ],
  "links": {
    "first": "https://example.com/api/posts?page=1",
    "last": "https://example.com/api/posts?page=12",
    "prev": null,
    "next": "https://example.com/api/posts?page=2"
  },
  "meta": {
    "current_page": 1,
    "from": 1,
    "last_page": 12,
    "path": "https://example.com/api/posts",
    "per_page": 20,
    "to": 20,
    "total": 235
  }
}

Три види пагінаторів:

Метод Що дає Ціна
paginate() номери сторінок, total, last_page додатковий COUNT(*)
simplePaginate() лише next/prev без підрахунку
cursorPaginate() курсор замість номера сторінки без OFFSET, стабільна на змінних даних

Як обрати:

  • адмінки й таблиці з переходом на довільну сторінку - paginate();
  • великі таблиці - COUNT(*) по мільйонах рядків дорогий, тож simplePaginate() або cursorPaginate();
  • стрічки й нескінченний скрол, мобільні застосунки - cursorPaginate(): без пропусків і дублікатів, коли між запитами додаються нові записи (зі OFFSET новий запис зсуває сторінки, і клієнт отримує один елемент двічі).

Що варто врахувати:

  • обмежити per_page зверху - інакше ?per_page=1000000 вивантажить усю таблицю;
  • стабільне сортування: для курсорної пагінації потрібне унікальне сортування (orderBy('created_at')->orderBy('id')), інакше записи з однаковою датою губляться;
  • параметри запиту зберігаються в посиланнях links через ->withQueryString() (фільтри, сортування);
  • N+1: with() до пагінації, а в ресурсі - whenLoaded;
  • власні метадані - метод paginationInformation() у класі колекції чи additional() для додаткових полів відповіді.

meta.total - частина контракту: перейшовши з paginate на cursorPaginate, ви прибираєте total, last_page і номери сторінок - це зміна, що ламає клієнтів.

Докладніше в документації: Laravel: API Resources і пагінація

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання