alanpoulain/api-platform-events-bundle
Install the Bundle
composer require alanpoulain/api-platform-events-bundle
Ensure ApiPlatformEventsBundle is enabled in config/bundles.php:
return [
// ...
ApiPlatform\EventsBundle\ApiPlatformEventsBundle::class => ['all' => true],
];
First Use Case: Logging Operations
Create a listener to log GraphQL operations (e.g., src/EventListener/ApiPlatformLogger.php):
namespace App\EventListener;
use ApiPlatform\Events\PreReadEvent;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class ApiPlatformLogger implements EventSubscriberInterface
{
public function __construct(private LoggerInterface $logger) {}
public static function getSubscribedEvents(): array
{
return [
PreReadEvent::class => 'logPreRead',
PostWriteEvent::class => 'logPostWrite',
];
}
public function logPreRead(PreReadEvent $event): void
{
$this->logger->info('Pre-read operation', [
'resource' => $event->getResource(),
'operation' => $event->getOperationName(),
'context' => $event->getContext(),
]);
}
// Add logPostWrite method similarly
}
Verify Events Trigger a GraphQL query/mutation (e.g., via API Platform’s GraphQL Playground) and check logs or debug output.
Conditional Logic in Events
Use events to modify behavior dynamically (e.g., PreWriteEvent for pre-saving data transformations):
public function onPreWrite(PreWriteEvent $event): void
{
$data = $event->getData();
if ($data['status'] === 'draft') {
$data['published_at'] = null;
$event->setData($data); // Modify input
}
}
Cross-Cutting Concerns
PreReadEvent/PreWriteEvent.PostWriteEvent.PostWriteEvent.Context Utilization
Access the context array for metadata (e.g., user roles, request headers):
$user = $event->getContext()['user'] ?? null;
if (!$user->hasRole('ROLE_ADMIN')) {
throw new \RuntimeException('Unauthorized');
}
Event Chaining Dispatch custom events within listeners to decouple logic:
$this->eventDispatcher->dispatch(new CustomEvent($event->getData()));
@PrePersist/@PostUpdate for hybrid logic.REST Limitation The bundle only supports GraphQL (per README). For REST, use API Platform’s native stages or wait for the Stages RFC.
Event Timing
PreDeserializeEvent/PostDeserializeEvent only fire for mutations, not queries.PreReadEvent fires before data fetching (use for early validation).Data Mutability
PostReadEvent) provide read-only data. Clone if modification is needed:
$data = clone $event->getData();
Context Overrides
Avoid modifying the context array directly—use setContext() if needed:
$event->setContext(array_merge($event->getContext(), ['custom_key' => 'value']));
debug:event-dispatcher to list dispatched events:
php bin/console debug:event-dispatcher
0). Higher values run later:
public static function getSubscribedEvents(): array
{
return [
PreWriteEvent::class => ['onPreWrite', 255], // High priority
];
}
Custom Events
Extend the bundle by creating your own events (e.g., PostProcessEvent) and dispatch them in listeners.
Event Subscriber Interfaces
Implement EventSubscriberInterface for type-safe event handling (IDE autocompletion).
Configuration Override default event classes by binding your own services (e.g., for testing):
# config/services.yaml
ApiPlatform\Events\PreReadEvent: '@app.custom_pre_read_event'
Performance
For high-traffic APIs, benchmark event listeners—some operations (e.g., DB queries in PreReadEvent) may impact performance. Use profiling tools like Blackfire.
How can I help you explore Laravel packages today?