Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.apivalk.com/llms.txt

Use this file to discover all available pages before exploring further.

For a strategy-picker and controller recipes, see the Add pagination how-to.

Route Configuration

To enable pagination for a specific route, you use the pagination() method on the Route object. This automatically handles the documentation and request parameter resolution (like page, limit, offset, or cursor).
use apivalk\apivalk\Router\Route\Pagination\Pagination;
use apivalk\apivalk\Router\Route\Route;

public static function getRoute(): Route
{
    return Route::get('/pets')
        ->pagination(Pagination::page()->setMaxLimit(50));
}

Supported Types

  • Pagination::page(): Standard page-based pagination (uses page and limit).
  • Pagination::offset(): Offset-based pagination (uses offset and limit).
  • Pagination::cursor(): Cursor-based pagination (uses cursor and limit).

Usage in Controller

When a route has pagination enabled, the AbstractApivalkRequest automatically creates the appropriate paginator object. You can access it via the paginator() method.

1. Fetching Data

Use the PaginatorFactory to resolve the paginator from the request and apply it to your repository or data source.
use apivalk\apivalk\Http\Request\Pagination\PaginatorFactory;

public function __invoke(ApivalkRequestInterface $request): AbstractApivalkResponse
{
    // The paginator is automatically resolved based on the Route configuration
    $paginator = $request->paginator();
    
    // Example for PagePaginator
    $pets = $this->petRepository->findAll(
        ($paginator->getPage() - 1) * $paginator->getLimit(),
        $paginator->getLimit()
    );
    
    // ...
}

2. Attaching Metadata to Response

After fetching your data, you must create a PaginationResponse object and attach it to your response. This ensures the pagination metadata (like total_pages or has_more) is included in the JSON output.
use apivalk\apivalk\Http\Response\Pagination\PagePaginationResponse;

// Inside Controller:
$totalEntries = $this->petRepository->count();
$totalPages = (int)ceil($totalEntries / $paginator->getLimit());
$hasMore = $paginator->getPage() < $totalPages;

$response = new GetPetsResponse($pets);
$response->setPaginationResponse(
    new PagePaginationResponse(
        $paginator->getPage(),
        $paginator->getLimit(),
        $hasMore,
        $totalPages
    )
);

return $response;

JSON Output Example

When a response has a pagination object attached, the JsonRenderer automatically includes a pagination key in the response body. The structure depends on the pagination type used.

Page Pagination

{
    "data": [...],
    "pagination": {
        "page": 1,
        "page_size": 20,
        "has_more": true,
        "total_pages": 5
    }
}

Offset Pagination

{
    "data": [...],
    "pagination": {
        "limit": 20,
        "offset": 40,
        "has_more": true,
        "total": 100
    }
}

Cursor Pagination

{
    "data": [...],
    "pagination": {
        "limit": 20,
        "current_cursor": "eyJpZCI6NDB9",
        "next_cursor": "eyJpZCI6NjB9",
        "has_more": true
    }
}