🀠
Saloon
GithubSupport Project
v2
v2
  • 🀠Saloon
  • Upgrade
    • 🎁What's new in v2
    • 🌿Upgrading from v1
  • Getting Started
    • πŸ‘‹Installation
  • The Basics
    • πŸ”ŒConnectors
    • βœ‰οΈRequests
    • πŸ€“Headers
    • ❓Query Parameters
    • πŸ”§HTTP Client Config
    • πŸ“¦Sending Body/Data
      • JSON Body
      • Multipart Form Body
      • Form Body (URL Encoded)
      • XML Body
      • String / Plain Text Body
      • Stream Body
    • πŸ”Authentication
    • πŸš€Sending Requests
    • πŸ“‘Responses
    • πŸ›€οΈData Transfer Objects
    • πŸ”₯Handling Failures
    • πŸͺBuilding SDKs
  • Digging Deeper
    • ☝️Solo Requests
    • πŸ“–Pagination v1 (Old)
    • πŸ“–Pagination v2
      • Paged Pagination
      • Limit/Offset Pagination
      • Cursor Pagination
      • Custom Pagination
    • 🎯Retrying Requests
    • 🏎️Concurrency & Pools
    • πŸ”‘OAuth2 Authentication
      • Authorization Code Grant
      • Client Credentials Grant
    • πŸ’‚Middleware
    • ⏸️Request Delay
    • πŸ›©οΈSenders
    • πŸ‘ͺPlugins
  • Plugins
    • β›΅Laravel Helpers
    • πŸ”Caching Responses
    • β›”Handling Rate Limits
    • 🏭SDK Generator
  • Testing
    • πŸ“ΈRecording Responses
    • 🚧Mock Responses
  • Conclusion
    • 🍳Cookbook
    • πŸ“šTutorials & Blog Posts
    • 🐞Known Issues
    • πŸ€—Credits
    • πŸŽ–οΈShowcase
    • ❀️Support
    • πŸ‘‹About Me
Powered by GitBook
On this page
  • Specifying a default per-page on the paginator
  • Assumptions made with the PagedPaginator
  • Useful Properties On The PagedPaginator
  • Next Steps
Edit on GitHub
  1. Digging Deeper
  2. Pagination v2

Paged Pagination

First, you will want to import the PagedPaginator class and return a new anonymous class that extends Saloon's PagedPaginator. This class expects the connector and request to be passed in via the constructor arguments.

<?php

use Saloon\Http\Response;
use Saloon\Http\Connector;
use Saloon\PaginationPlugin\PagedPaginator;
use Saloon\PaginationPlugin\Contracts\HasPagination;

class SpotifyConnector extends Connector implements HasPagination
{
    // ...
    
    public function paginate(Request $request): PagedPaginator
    {
        return new class(connector: $this, request: $request) extends PagedPaginator
        {
            //
        };
    }
}

You don't need to use an anonymous class if it doesn't fit your code style. It is recommended to reduce the number of classes, but you can create your own pagination class that extends the base paginator if you prefer.

After you have defined your paginator class, you will be required to define two protected methods which are used to power the paginator. These methods are:

  • isLastPage - This method is used to tell the paginator when to stop processing. Here you can use the response class provided to determine if you are on the last page. Some APIs may provide metadata like remaining results or next page URLs which you can use to check if you are on the last page. Additionally, Saloon has a few properties that can be used to determine if you are on the last page.

  • getPageItems - This method is used to return the array of results inside of each page. This is used when using the items or collect method on your paginator class.

Let's implement these two methods on our paginator and dive into how it works.

<?php

use Saloon\Http\Response;
use Saloon\Http\Connector;
use Saloon\PaginationPlugin\PagedPaginator;
use Saloon\PaginationPlugin\Contracts\HasPagination;

class SpotifyConnector extends Connector implements HasPagination
{
    // ...
    
    public function paginate(Request $request): PagedPaginator
    {
        return new class(connector: $this, request: $request) extends PagedPaginator
        {
            protected function isLastPage(Response $response): bool
            {
                return is_null($response->json('next_page_url'));
            }
            
            protected function getPageItems(Response $response, Request $request): array
            {
                return $response->json('items');
            }
        };
    }
}

Let's assume in this hypothetical example that the API provides some useful information to see if we're on the last page. In this example, we know we're on the last page if the next_page_url JSON property on the body is null. There are various other ways of knowing if you are on the last page, so it's best to fully understand your API's pagination.

To get the page items, we'll use the json method on the response to access the items array from the body.

Specifying a default per-page on the paginator

The third-party API you are integrating with may require you to define a page size (per page) on your requests, or you may want to set a default page size used for every request. You can set this default page size as a property on the paginator class.

public function paginate(Request $request): PagedPaginator
{
    return new class(connector: $this, request: $request) extends PagedPaginator
    {
        protected ?int $perPageLimit = 100;
        
        // ...
    }
}

You may also use the setPerPageLimit method on an instantiated paginator if you want to configure it on the fly. You must set this before iterating over the paginator.

$spotifyConnector = new SpotifyConnector;

$paginator = $spotifyConnector->paginate($request);

$paginator->setPerPageLimit(250);

// foreach($paginator as $response) { ... }

Assumptions made with the PagedPaginator

The PagedPaginator will apply pagination by sending two query parameters:

  • page

  • per_page

This assumption might not be the way your third-party API works. You can really easily change this by extending the applyPagination method. For example, let's say our API expects a "currentPage" and a "pageSize" instead. We can simply extend the applyPagination method and change the keys. You can apply the pagination in whichever the API requires.

public function paginate(Request $request): PagedPaginator
{
    return new class(connector: $this, request: $request) extends PagedPaginator
    {
        protected function isLastPage(Response $response): bool
        {
            return is_null($response->json('next_page_url'));
        }
        
        protected function getPageItems(Response $response, Request $request): array
        {
            return $response->json('items');
        }
        
        protected function applyPagination(Request $request): Request
        {
            $request->query()->add('currentPage', $this->currentPage);
    
            if (isset($this->perPageLimit)) {
                $request->query()->add('pageSize', $this->perPageLimit);
            }
    
            return $request;
        }
    };
}

Useful Properties On The PagedPaginator

We previously mentioned that the PagedPaginator class provides a few methods that can be used to help with last-page calculation. These methods are:

  • totalResults - An integer which will return the total number of items returned. This can be used to check if it's equal to the number of total results in the list.

  • currentPage - An integer which will return the current page that the paginator is currently on.

Next Steps

PreviousPagination v2NextLimit/Offset Pagination

Last updated 1 year ago

After configuring your paginator, head back to the section of the documentation.

πŸ“–
Using The Paginator