API Platform Integration
API Platform integration is provided by the package
rekalogika/rekapager-api-platform
.
Installation
Preinstallation checklists:
- Make sure Composer is installed globally, as explained in the installation
chapter of the Composer
documentation. Run
composer about
to verify. - Make sure your project has Symfony Flex installed and enabled (it is enabled
by default). Run
composer why symfony/flex
to verify.
Open a command console, enter your project directory, and execute:
composer require rekalogika/rekapager-api-platform
API Changes
This package aims to implement keyset pagination by changing the type of the existing 'page' query parameter from integer to string.
{
"@context": "/api/contexts/Post",
"@id": "/api/posts",
"@type": "hydra:Collection",
"hydra:member": [
...
],
"hydra:view": {
"@type": "hydra:PartialCollectionView",
"@id": "/api/posts",
- "hydra:last": "/api/posts?page=21",
- "hydra:next": "/api/posts?page=2"
+ "hydra:last": "/api/posts?page=q1YqU7KKjtVRKlCy0jXUUcpRssorzcnRUcpXsjLQUSpRslIqVaoFAA",
+ "hydra:next": "/api/posts?page=q1YqU7KqVsrXy0xRsjI2qNVRKlCyMtJRylGyyivNydFRyleyMtBRKlGyAgrVAgA"
}
}
The change should be transparent to the consumers of the API, and does not require any changes, as long as they traverse the set by using the URIs as they are returned by the API.
However, if the consumer currently increments the page number manually on their
side, they need to change how they go to the next page by using the URI provided
by the API (hydra:next
) instead. Clients that still use the integer page
number (after switching to keyset pagination) will get a 400 Bad Request
response.
The change is opt-in and can be enabled per operation or globally. You will be able to keep the standard API Platform pagination system, then make sure all the consumers conform to the required behavior, and enable it only after everyone is ready.
The parameter page=1
is special and will not cause a 400 error response. It
will be treated as a request for the first page.
If your API does not use JSON-LD, your consumer can get the related URIs using
the Link
header. Example:
Link: </api/posts?page=q1YqU7KqVsrXy0xRsjI2qNVRKlCyMtJRylGyyivNydFRyleyMtBRKlGyAgrVAgA>; rel="next",
</api/posts?page=q1YqU7KKjtVRKlCy0jXUUcpRssorzcnRUcpXsjLQUSpRslIqVaoFAA>; rel="last",
<http://127.0.0.1:8000/api/docs.jsonld>; rel="http://www.w3.org/ns/hydra/core#apiDocumentation"
Provided Components
- A decorator for
OpenApiFactoryInterface
that changes the type of every 'page' query parameter from integer to string. It should still be compatible with API Platform's standard pagination system. PagerNormalizer
: a normalizer forPagerInterface
.RekapagerExtension
: an extension for API Platform's Doctrine ORM integration to use Rekapager.PagerFactory
: creates aPagerInterface
object from aPageableInterface
, the current operation, and the context. Useful in a state provider or processor.RekapagerLinkProcessor
: add the links to theLink
HTTP header.
Usage in a State Provider or Processor
In a state provider, you can use PagerFactoryInterface
to transform any
PageableInterface
into a PagerInterface
. Then, you can simply return the
pager instance and our PagerNormalizer
will output it correctly.
use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProviderInterface;
use Rekalogika\Rekapager\ApiPlatform\PagerFactoryInterface;
use Rekalogika\Rekapager\Doctrine\Collections\SelectableAdapter;
use Rekalogika\Rekapager\Keyset\KeysetPageable;
/**
* @implements ProviderInterface<Post>
*/
class PostProvider implements ProviderInterface
{
public function __construct(
private PagerFactoryInterface $pagerFactory,
) {
}
public function provide(
Operation $operation,
array $uriVariables = [],
array $context = []
): object|array|null {
$pageable = ...; // Get or create a PageableInterface object here
$pager = $this->pagerFactory->createPager($pageable, $operation, $context);
return $pager;
}
}
PagerFactory
should respect these standard API Platform settings in the
operation, as well as their corresponding global settings.
paginationItemsPerPage
: the number of items per page.paginationClientEnabled
: whether to enable the pagination settings from the client.paginationClientItemsPerPage
: the number of items per page that the client requested.paginationMaximumItemsPerPage
Doctrine ORM Support
This package supports the pagination for API Platform's Doctrine ORM integration
as an alternative to the default pagination. Its usage is opt-in. You can enable
it per operation using the rekapager_orm_enabled
extra property:
#[ApiResource(
extraProperties: [
'rekapager_orm_enabled' => true
]
)]
class Post
{
// ...
}
To enable it globally, you can set it in the configuration:
api_platform:
defaults:
extra_properties:
rekapager_orm_enabled: true