To retrieve data exposed by the API, API Platform uses classes called data providers. A data provider using Doctrine ORM to retrieve data from a database is included with the library and is enabled by default. This data provider natively supports paged collections and filters. It can be used as is and fits perfectly with common usages.
However, you sometime want to retrieve data from other sources such as another persistence layer, a webservice, ElasticSearch or MongoDB. Custom data providers can be used to do so. A project can include as many data providers as it needs. The first able to retrieve data for a given resource will be used.
For a given resource, you can implement two kind of interfaces:
CollectionDataProviderInterface
is used when fetching a collection.ItemDataProviderInterface
is used when fetching items.In the following examples we will create custom data providers for an entity class called AppBundle\Entity\BlogPost
.
Note, that if your entity is not Doctrine-related, you need to flag the identifier property by using @ApiProperty(identifier=true)
for things to work properly (see also Entity Identifier Case).
First, your BlogPostCollectionDataProvider
has to implement the CollectionDataProviderInterface
:
The getCollection
method must return an array
, a Traversable
or a ApiPlatform\Core\DataProvider\PaginatorInterface
instance.
If no data is available, you should return an empty array.
<?php
// src/AppBundle/DataProvider/BlogPostCollectionDataProvider.php
namespace AppBundle\DataProvider;
use AppBundle\Entity\BlogPost;
use ApiPlatform\Core\DataProvider\CollectionDataProviderInterface;
use ApiPlatform\Core\Exception\ResourceClassNotSupportedException;
final class BlogPostCollectionDataProvider implements CollectionDataProviderInterface
{
public function getCollection(string $resourceClass, string $operationName = null)
{
if (BlogPost::class !== $resourceClass) {
throw new ResourceClassNotSupportedException();
}
// Retrieve the blog post collection from somewhere
return [new BlogPost(1), new BlogPost(2)];
}
}
Then declare a Symfony service, for example:
# app/config/services.yml
services:
# ...
'AppBundle\DataProvider\BlogPostCollectionDataProvider':
tags: [ { name: 'api_platform.collection_data_provider', priority: 2 } ]
Tagging the service with the tag api_platform.collection_data_provider
will enable API Platform Core to automatically
register and use this data provider. The optional attribute priority
allows to define the order in which the
data providers are called. The first data provider not throwing a ApiPlatform\Core\Exception\ResourceClassNotSupportedException
will be used.
The process is similar for item data providers. Create a BlogPostItemDataProvider
implementing the ItemDataProviderInterface
interface:
The getItem
method can return null
if no result has been found.
<?php
// src/AppBundle/DataProvider/BlogPostItemDataProvider.php
namespace AppBundle\DataProvider;
use AppBundle\Entity\BlogPost;
use ApiPlatform\Core\DataProvider\ItemDataProviderInterface;
use ApiPlatform\Core\Exception\ResourceClassNotSupportedException;
final class BlogPostItemDataProvider implements ItemDataProviderInterface
{
public function getItem(string $resourceClass, $id, string $operationName = null, array $context = []) {
if (BlogPost::class !== $resourceClass) {
throw new ResourceClassNotSupportedException();
}
// Retrieve the blog post item from somewhere then return it or null if not found
return new BlogPost($id);
}
}
If service autowiring and autoconfiguration are enabled (it’s the case by default), you are done!
Otherwise, if you use a custom dependency injection configuration, you need to register the corresponding service and add the
api_platform.item_data_provider
tag to it. As for collection data providers, the priority
attribute can be used to order
providers.
# app/config/services.yml
services:
# ...
'AppBundle\DataProvider\BlogPostItemDataProvider':
tags: [ 'api_platform.item_data_provider' ]
Made with love by
Les-Tilleuls.coop can help you design and develop your APIs and web projects, and train your teams in API Platform, Symfony, Next.js, Kubernetes and a wide range of other technologies.
Learn more