// src/App/Entity.php
namespace App\Entity;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\QueryParameter;
use Doctrine\ORM\Mapping as ORM;
#[GetCollection(
uriTemplate: 'books{._format}',
parameters: [
':property' => new QueryParameter(filter: 'app.search_filter'),
]
)]
#[ORM\Entity]
class Book
{
#[ORM\Id, ORM\Column, ORM\GeneratedValue]
public ?int $id = null;
#[ORM\Column]
public ?string $title = null;
#[ORM\Column]
public ?string $author = null;
}
// src/App/DependencyInjection.php
namespace App\DependencyInjection;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
function configure(ContainerConfigurator $configurator): void
{
$services = $configurator->services();
$services->set('app.search_filter')
->parent('api_platform.doctrine.orm.search_filter')
->args([['author' => 'partial', 'title' => 'partial']])
->tag('api_platform.filter');
}
// src/App/Playground.php
namespace App\Playground;
use Symfony\Component\HttpFoundation\Request;
function request(): Request
{
return Request::create('/books.jsonld?author=a', 'GET');
}
// src/DoctrineMigrations.php
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
final class Migration extends AbstractMigration
{
public function up(Schema $schema): void
{
$this->addSql('CREATE TABLE book (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, title VARCHAR(255) NOT NULL, author VARCHAR(255) NOT NULL)');
}
}
// src/App/Fixtures.php
namespace App\Fixtures;
use App\Entity\Book;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
use function Zenstruck\Foundry\anonymous;
use function Zenstruck\Foundry\faker;
use function Zenstruck\Foundry\repository;
final class BookFixtures extends Fixture
{
public function load(ObjectManager $manager): void
{
$bookFactory = anonymous(Book::class);
if (repository(Book::class)->count()) {
return;
}
$bookFactory->many(10)->create(fn () => [
'title' => faker()->name(),
'author' => faker()->firstName(),
]);
}
}
// src/App/Tests.php
namespace App\Tests;
use ApiPlatform\Playground\Test\TestGuideTrait;
use ApiPlatform\Symfony\Bundle\Test\ApiTestCase;
use App\Entity\Book;
final class BookTest extends ApiTestCase
{
use TestGuideTrait;
public function testGetDocumentation(): void
{
static::createClient()->request('GET', '/books.jsonld');
$this->assertResponseIsSuccessful();
$this->assertMatchesResourceCollectionJsonSchema(Book::class, '_api_books{._format}_get_collection', 'jsonld');
$this->assertJsonContains([
'hydra:search' => [
'@type' => 'hydra:IriTemplate',
'hydra:template' => '/books.jsonld{?author,title}',
'hydra:variableRepresentation' => 'BasicRepresentation',
'hydra:mapping' => [
[
'@type' => 'IriTemplateMapping',
'variable' => 'author',
'property' => 'author',
'required' => false,
],
[
'@type' => 'IriTemplateMapping',
'variable' => 'title',
'property' => 'title',
'required' => false,
],
],
],
]);
}
}
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