3slab/vdm-library-http-transport-bundle
Install the Bundle
composer require 3slab/vdm-library-http-transport-bundle
Enable the bundle in config/bundles.php:
return [
// ...
VdmLibrary\HttpTransportBundle\VdmLibraryHttpTransportBundle::class => ['all' => true],
];
Configure the Transport
Add the transport to your config/packages/messenger.yaml:
framework:
messenger:
transports:
http_source:
dsn: "https://api.example.com/data"
options:
method: GET
http_options: { headers: { 'Accept': 'application/json' } }
First Use Case: Fetching External Data Dispatch a message to trigger the HTTP request:
use Symfony\Component\Messenger\MessageBusInterface;
public function __construct(private MessageBusInterface $bus) {}
public function fetchData(): void
{
$this->bus->dispatch(new FetchDataMessage());
}
Ensure FetchDataMessage is a valid message class (e.g., new class {}).
Polling External APIs
Use a Message class to encapsulate HTTP fetch logic:
class FetchUserDataMessage implements MessageInterface {}
Configure a bus to handle the message with the HTTP transport:
framework:
messenger:
buses:
http_bus:
middleware: [validate, http_transport]
transports: [http_source]
Handling Responses
Process responses via a Handler:
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
#[AsMessageHandler]
public function handle(FetchDataMessage $message, HttpResponseInterface $response)
{
$data = json_decode($response->getContent(), true);
// Process $data (e.g., save to DB, dispatch another message)
}
Retry Logic
Leverage built-in retry options (configured in messenger.yaml):
options:
retry:
enabled: true
number: 3
timeBeforeRetry: 10 # seconds
http_options (e.g., auth, timeouts):
options:
http_options:
auth_bearer_token: "%env(API_TOKEN)%"
timeout: 30
options:
monitoring:
enabled: true
options:
http_executor: app.custom_http_executor
Define the executor as a service:
// config/services.yaml
services:
app.custom_http_executor:
class: App\CustomHttpExecutor
tags: ['messenger.http_executor']
Retry Strategy Misconfiguration
retry_strategy.max_retries to a value other than 0 will fail silently.max_retries: 0 in the retry strategy (even if retries are enabled via options.retry).DSN Format
dsn must start with http:// or https://. Relative URLs or missing schemes will throw errors.Response Handling
HttpResponseInterface in handlers may not match expectations (e.g., non-200 status codes).if ($response->getStatusCode() !== 200) {
throw new \RuntimeException('API request failed');
}
Middleware Order
http_transport after validation middleware may cause unnecessary retries for invalid messages.buses:
http_bus:
middleware: [http_transport, validate] # Transport first
Log HTTP Requests/Responses
Use Symfony’s HttpClient logger or add a custom middleware:
options:
http_options:
logger: app.http_logger
Define the logger service to log requests/responses.
Check Transport Status Verify the transport is registered:
php bin/console debug:messenger:transports
Look for http_source in the output.
Custom Response Processors
Extend the bundle’s HttpResponseFactory to transform responses:
// src/EventSubscriber/HttpResponseSubscriber.php
use Symfony\Component\Messenger\Event\WorkerMessageFailedEvent;
class HttpResponseSubscriber implements SubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
WorkerMessageFailedEvent::class => 'onFailure',
];
}
public function onFailure(WorkerMessageFailedEvent $event): void
{
if ($event->getEnvelope()->getMessage() instanceof FetchDataMessage) {
$event->setMessage(new RetryFetchDataMessage());
}
}
}
Dynamic DSN Configuration Use environment variables or parameters for flexible DSNs:
dsn: "%env(HTTP_SOURCE_DSN)%"
Define the env var in .env:
HTTP_SOURCE_DSN=https://dynamic-api.example.com
Async Processing
Combine with async transport for high-throughput polling:
transports:
http_source:
dsn: "https://api.example.com"
options: { ... }
async: async://
buses:
async_bus:
transports: [async, http_source]
How can I help you explore Laravel packages today?