Install the Bundle
composer require elandlord/nats-php-bundle
Ensure elandlord/nats-php-bundle is registered in config/bundles.php.
Configure NATS Connection
Add NATS settings to .env:
NATS_URL=nats://localhost:4222
NATS_USER= # Optional
NATS_PASS= # Optional
Publish the default config:
php bin/console config:dump-reference elandlord_nats
First Use Case: Sending a Message Create a Symfony Messenger message class:
// src/Message/ExampleMessage.php
namespace App\Message;
class ExampleMessage {
public string $content;
}
Send it via Messenger:
use App\Message\ExampleMessage;
use Symfony\Component\Messenger\MessageBusInterface;
public function __construct(private MessageBusInterface $bus) {}
public function sendExample(): void {
$this->bus->dispatch(new ExampleMessage('Hello NATS!'));
}
Verify NATS Integration
Check NATS server logs or use a client like nats-cli to confirm messages are published.
$this->bus->dispatch(new MyMessage($payload));
config/packages/messenger.yaml:
messenger:
transports:
nats:
dsn: '%env(NATS_URL)%'
options:
user: '%env(NATS_USER)%'
pass: '%env(NATS_PASS)%'
serializer component. Customize via messenger.transport.nats.options.serializer.# config/packages/messenger.yaml
messenger:
workers:
nats_worker:
transport: nats
retry_strategy:
max_retries: 3
delay: 1000
Run the worker:
php bin/console messenger:consume nats_worker -vv
// src/MessageHandler/ExampleHandler.php
namespace App\MessageHandler;
use App\Message\ExampleMessage;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
#[AsMessageHandler]
class ExampleHandler {
public function __invoke(ExampleMessage $message) {
// Process $message->content
}
}
use Elandlord\NatsBundle\Messenger\Transport\NatsTransport;
$transport = $this->container->get(NatsTransport::class);
$response = $transport->request('reply.subject', new RequestMessage($data));
messenger.yaml:
messenger:
transports:
nats:
options:
use_jetstream: true
stream_name: my_stream
use Elandlord\NatsBundle\Nats\NatsConnection;
public function __construct(private NatsConnection $nats) {}
public function publishRaw(): void {
$this->nats->publish('subject', 'raw payload');
}
messenger:
transports:
nats:
options:
middleware:
- App\Middleware\NatsLoggingMiddleware
League\Container or Symfony’s TestContainer:
use Elandlord\NatsBundle\Tests\MockNatsConnection;
$container->set(NatsConnection::class, MockNatsConnection::class);
NatsConnection (auto-managed by Symfony). Avoid manual new NatsConnection().ConnectionException in logs if messages fail silently.JsonSerializable or configure a custom serializer:
messenger:
transports:
nats:
options:
serializer: App\Serializer\CustomSerializer
stream_name and subject in messenger.yaml:
options:
use_jetstream: true
stream_name: my_stream
subject: my.subject
messenger.yaml:
retry_strategy:
max_retries: 3
delay: 1000
multiplier: 2
app.events.user.created) and document them.messenger:
transports:
nats:
options:
logger: true
monolog channel for NATS events.nats-cli to inspect subjects, streams, and connections:
nats-cli list subjects
nats-cli consume my.subject
| Error | Cause | Solution |
|---|---|---|
Connection refused |
NATS server unreachable | Verify NATS_URL and server status. |
Serialization failure |
Invalid payload format | Check message class implements JsonSerializable. |
Stream not found |
JetStream misconfiguration | Ensure stream_name is correct. |
Message timeout |
Slow handler | Increase messenger.transport.nats.timeout. |
NatsTransport for custom behavior:
use Elandlord\NatsBundle\Messenger\Transport\NatsTransport;
class CustomNatsTransport extends NatsTransport {
protected function doSend(): void {
// Custom logic
}
}
Register it in config/packages/messenger.yaml:
transports:
custom_nats:
dsn: '%env(NATS_URL)%'
class: App\Transport\CustomNatsTransport
use Elandlord\NatsBundle\Event\NatsConnectedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class NatsSubscriber implements EventSubscriberInterface {
public static function getSubscribedEvents(): array {
return [
NatsConnectedEvent::class => 'onNatsConnected',
];
}
public function onNatsConnected(NatsConnectedEvent $event): void {
// Handle connection
}
}
use Elandlord\NatsBundle\Messenger\Middleware\MiddlewareInterface;
class LoggingMiddleware implements MiddlewareInterface {
public function handle(Envelope $envelope, StackInterface $stack): Envelope {
// Log before/after
return $stack->next($envelope);
}
}
Register in messenger.yaml:
messenger:
transports:
nats:
options:
middleware:
- App\Middleware\LoggingMiddleware
How can I help you explore Laravel packages today?