Api Platform conference
Register now
Guides How to create a Guide
API Platform Conference
September 19-20, 2024 | Lille & online

The international conference on the API Platform Framework

Get ready for game-changing announcements for the PHP community!

The API Platform Conference 2024 is happening soon, and it's close to selling out.
API Platform 4, Caddy web server, Xdebug, AI... Enjoy two days of inspiring talks with our friendly community and our amazing speakers.

Only a few tickets left!
Guide

How to create a Guide

This guide describes every available options to create a guide. Everything is optional and we recommend not to use Doctrine unless the guide is doctrine-specific. We provide a SQLite database, a way to run migrations and fixtures if needed. Usually a guide has a Front Matter header:

slug: how-to
name: How to create a Guide
// When this is true we'll be able to run the guide in api-platform.com/playground
executable: false
position: 0
tags: [doctrine]

Two namespaces are available to register API resources: App\Entity (for Doctrine) and App\ApiResource.

// src/App/Entity.php
namespace App\Entity;
use ApiPlatform\Metadata\ApiResource;
use Doctrine\ORM\Mapping as ORM;
To showcase all the guide possibilities we’re using a Doctrine Entity Book:
#[ApiResource]
#[ORM\Entity]
class Book
{
    #[ORM\Id, ORM\Column, ORM\GeneratedValue]
    private ?int $id = null;
    #[ORM\Column]
    public ?string $title = null;
    public function getId(): ?int
    {
        return $this->id;
    }
}
We can declare as many namespaces or classes that we need to for this code to work.
// src/App/Service.php
namespace App\Service;
use Psr\Log\LoggerInterface;
class MyService
{
    public function __construct(private LoggerInterface $logger)
    {
    }
}
If you need to change something within Symfony’s Container you need to declare this namespace with a configure method.
// src/App/DependencyInjection.php
namespace App\DependencyInjection;
use App\Service\MyService;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use function Symfony\Component\DependencyInjection\Loader\Configurator\service;
function configure(ContainerConfigurator $configurator): void
{
    $services = $configurator->services();
    $services->set(MyService::class)
        ->args([service('logger')]);
}
Doctrine migrations will run from this namespace.
// 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)');
    }
}
And we can load fixtures using Foundry
// 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;
final class BookFixtures extends Fixture
{
    public function load(ObjectManager $manager): void
    {
        $bookFactory = anonymous(Book::class);
        $bookFactory->many(10)->create([
            'title' => 'title',
        ]);
    }
}
The request method is the one executed by the API Platform online Playground on startup.
// src/App/Playground.php
namespace App\Playground;
use Symfony\Component\HttpFoundation\Request;
function request(): Request
{
    return Request::create('/books.jsonld', 'GET');
}
The Guide huge advantage is that it is also tested with phpunit.
// 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 testAsAnonymousICanAccessTheDocumentation(): void
    {
        $response = static::createClient()->request('GET', '/books.jsonld');
        $this->assertResponseIsSuccessful();
        $this->assertMatchesResourceCollectionJsonSchema(Book::class, '_api_/books{._format}_get_collection', 'jsonld');
        $this->assertNotSame(0, $response->toArray(false)['hydra:totalItems'], 'The collection is empty.');
        $this->assertJsonContains([
            'hydra:totalItems' => 10,
        ]);
    }
}

You can also help us improve this guide.

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

Copyright © 2023 Kévin Dunglas

Sponsored by Les-Tilleuls.coop