dbp/relay-base-publication-bundle
Installation
composer require dbp/relay-base-publication-bundle
Add the bundle to config/bundles.php:
DigitalBlueprint\RelayBasePublicationBundle\DigitalBlueprintRelayBasePublicationBundle::class => ['all' => true],
Configuration Publish the default config:
php bin/console dbp:relay:config:init
Review and customize config/packages/digital_blueprint_relay_base_publication.yaml.
First Use Case Create a basic publication endpoint:
php bin/console make:dbp-publication MyPublication
This generates a skeleton in src/Publication/MyPublication/.
docs/README.md: Core concepts, architecture, and API design.config/packages/digital_blueprint_relay_base_publication.yaml: Default settings (e.g., API routes, middleware, serialization).src/Publication/: Example publication structures (e.g., MyPublication/Controller.php, MyPublication/Resource.php).Define a Publication:
Extend DigitalBlueprint\RelayBasePublicationBundle\Publication\AbstractPublication:
namespace App\Publication\MyPublication;
use DigitalBlueprint\RelayBasePublicationBundle\Publication\AbstractPublication;
class MyPublication extends AbstractPublication
{
protected string $name = 'my_publication';
protected string $description = 'My custom publication';
public function getData(): array
{
return ['key' => 'value'];
}
}
Register in services.yaml:
services:
App\Publication\MyPublication\MyPublication:
tags: ['dbp.relay.publication']
Route Handling:
The bundle auto-registers routes under /api/publications/{name} (configurable). Use #[Route] for custom paths if needed.
Resources:
Implement DigitalBlueprint\RelayBasePublicationBundle\Publication\ResourceInterface:
namespace App\Publication\MyPublication;
use DigitalBlueprint\RelayBasePublicationBundle\Publication\ResourceInterface;
class MyResource implements ResourceInterface
{
public function toArray($data): array
{
return ['data' => $data];
}
}
Bind the resource in MyPublication:
protected string $resourceClass = MyResource::class;
Custom Serializers:
Override getSerializer() in AbstractPublication to use Symfony’s SerializerInterface or a custom implementation.
config/packages/digital_blueprint_relay_base_publication.yaml:
relay:
middleware:
- App\Middleware\MyMiddleware
addMiddleware() in your publication class:
public function build(): void
{
$this->addMiddleware(MyMiddleware::class);
}
AbstractPublication and test getData()/getResource():
$publication = $this->createMock(MyPublication::class);
$publication->method('getData')->willReturn(['test' => true]);
$this->assertEquals(['data' => ['test' => true]], $publication->getResource()->toArray($publication->getData()));
client->request('GET', '/api/publications/my_publication') and assert responses.DigitalBlueprint\RelayBasePublicationBundle\Event\PublicationEvent:
namespace App\EventListener;
use DigitalBlueprint\RelayBasePublicationBundle\Event\PublicationEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class MySubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
PublicationEvent::PRE_FETCH => 'onPreFetch',
];
}
public function onPreFetch(PublicationEvent $event): void
{
$event->setData(['modified' => true]);
}
}
/api/publications) is not configurable via YAML. Override getRoutePrefix() in your publication class if needed.
protected function getRoutePrefix(): string
{
return '/custom/prefix';
}
config/packages/digital_blueprint_relay_base_publication.yaml:
relay:
cache: true # Defaults to false
Clear cache after changes:
php bin/console cache:clear
Enable Verbose Logging:
Set in .env:
DBP_RELAY_DEBUG=1
Logs appear in var/log/dev.log.
Common Issues:
dbp.relay.publication and the class implements AbstractPublication.ResourceInterface implementations with php bin/console debug:container App\Publication\MyPublication\MyResource.#[ORM\LazyLoadingProxy] for Doctrine entities in publications to defer loading until serialization.getData() with pagination:
public function getData(int $page = 1, int $limit = 20): array
{
return $this->entityManager->getRepository(MyEntity::class)
->createQueryBuilder('e')
->setFirstResult(($page - 1) * $limit)
->setMaxResults($limit)
->getQuery()
->getResult();
}
supportedMethods() in AbstractPublication:
protected function supportedMethods(): array
{
return ['GET', 'POST'];
}
AbstractPublication and overriding checkAccess():
protected function checkAccess(): bool
{
return $this->security->isGranted('ROLE_USER');
}
ResourceInterface to return GraphQL-compatible data and use overblog/graphql-bundle for serialization.composer.json for breaking changes between minor versions.MyPublication entity mappings align with the bundle’s expected structure (e.g., id, createdAt).How can I help you explore Laravel packages today?