gdx/p-service-bus-laravel-package
Laravel package integrating the GDX P Service Bus into your app, providing configuration and helpers to publish and consume messages for service-to-service communication via a service bus.
Installation
composer require gdx/p-service-bus-laravel-package
Publish the config file:
php artisan vendor:publish --provider="Gdx\PServiceBus\PServiceBusServiceProvider" --tag="config"
Configuration
Edit config/p-service-bus.php to define your service bus endpoints, queues, and message types. Example:
'endpoints' => [
'default' => [
'host' => env('SERVICE_BUS_HOST'),
'username' => env('SERVICE_BUS_USERNAME'),
'password' => env('SERVICE_BUS_PASSWORD'),
],
],
'queues' => [
'orders' => 'orders-queue',
'payments' => 'payments-queue',
],
First Use Case: Sending a Message
Define a message class (e.g., app/ServiceBus/Messages/OrderCreated.php):
namespace App\ServiceBus\Messages;
use Gdx\PServiceBus\Messages\Message;
class OrderCreated extends Message
{
public function __construct(public string $orderId, public float $total) {}
}
Send it via a facade:
use Gdx\PServiceBus\Facades\PServiceBus;
PServiceBus::send(new OrderCreated('123', 99.99), 'orders');
First Use Case: Receiving a Message
Register a handler in config/p-service-bus.php:
'handlers' => [
'App\ServiceBus\Messages\OrderCreated' => [
'handler' => 'App\ServiceBus\Handlers\OrderCreatedHandler',
'queue' => 'orders',
],
],
Implement the handler:
namespace App\ServiceBus\Handlers;
use App\ServiceBus\Messages\OrderCreated;
use Gdx\PServiceBus\Handlers\MessageHandler;
class OrderCreatedHandler implements MessageHandler
{
public function handle(OrderCreated $message)
{
// Process the order
}
}
Decoupled Communication
Use the service bus to decouple services (e.g., OrderService publishes OrderCreated, NotificationService subscribes via OrderCreatedHandler). Example:
// In OrderService
PServiceBus::send(new OrderCreated($orderId, $total));
// In NotificationService (handler)
public function handle(OrderCreated $message) {
Mail::to($message->customerEmail)->send(new OrderConfirmation($message->orderId));
}
Retry Logic
Configure retries in config/p-service-bus.php:
'retry_policy' => [
'max_retries' => 3,
'delay' => 1000, // ms
],
Use PServiceBus::sendWithRetry() for transient failures.
Dead Letter Queues (DLQ) Define a DLQ in config:
'dead_letter_queue' => 'dlq-orders',
Messages failing after retries are moved to dlq-orders.
Batching Send multiple messages in a batch:
PServiceBus::sendBatch([
new OrderCreated('123', 99.99),
new OrderCreated('456', 149.99),
], 'orders');
Laravel Events → Service Bus Convert Laravel events to service bus messages in an event listener:
public function handle(OrderCreatedEvent $event)
{
PServiceBus::send(new OrderCreated($event->orderId, $event->total));
}
Service Bus → Laravel Jobs Use handlers to dispatch Laravel jobs:
public function handle(OrderCreated $message)
{
ProcessOrderJob::dispatch($message->orderId);
}
Schema Validation Validate messages using Laravel’s validation rules in handlers:
use Illuminate\Support\Facades\Validator;
public function handle(OrderCreated $message)
{
$validator = Validator::make([
'orderId' => $message->orderId,
'total' => $message->total,
], [
'orderId' => 'required|string',
'total' => 'required|numeric|min:0',
]);
if ($validator->fails()) {
throw new \RuntimeException('Invalid message: ' . $validator->errors()->first());
}
}
Testing Mock the service bus in tests:
$this->mock(PServiceBus::class)->shouldReceive('send')
->once()
->withArgs(function ($message) {
return $message instanceof OrderCreated;
});
Message Serialization
__serialize()/__unserialize():
public function __serialize(): array
{
return ['orderId' => $this->orderId, 'total' => $this->total];
}
public function __unserialize(array $data): void
{
$this->orderId = $data['orderId'];
$this->total = $data['total'];
}
Handler Registration
config/p-service-bus.php.public function boot()
{
PServiceBus::registerHandlers([
OrderCreated::class => OrderCreatedHandler::class,
]);
}
Queue Binding
config/p-service-bus.php have corresponding handlers.Performance Overhead
PServiceBus::dispatch(new OrderCreated('123', 99.99))->onQueue('high-priority');
Error Handling
public function handle(OrderCreated $message)
{
try {
// Logic here
} catch (\Exception $e) {
Log::error("Failed to handle OrderCreated: " . $e->getMessage());
throw $e; // Re-throw to trigger retry or DLQ
}
}
Enable Logging
Add to config/p-service-bus.php:
'logging' => [
'enabled' => true,
'channel' => 'single',
],
Check logs for message flow:
[PServiceBus] Sent message [OrderCreated] to queue [orders].
[PServiceBus] Processed message [OrderCreated] in 120ms.
Inspect Queues Use the service bus CLI to list messages:
php artisan p-service-bus:list-messages orders
Common Errors
MessageNotFoundException: Ensure message classes are properly namespaced and extend Gdx\PServiceBus\Messages\Message.QueueNotFoundException: Verify queue names in config match the service bus namespace.AuthenticationException: Check SERVICE_BUS_HOST, SERVICE_BUS_USERNAME, and SERVICE_BUS_PASSWORD in .env.Custom Message Types
Extend the base Message class to add metadata:
class OrderCreated extends Message
{
public function __construct(
public string $orderId,
public float $total,
public ?string $priority = null
) {}
public function getMetadata(): array
{
return ['priority' => $this->priority];
}
}
Middleware Add middleware to handlers for cross-cutting concerns (e.g., logging, auth):
PServiceBus::addHandlerMiddleware(OrderCreatedHandler::class, function ($handler, $message) {
Log::info("Handling {$message::class} with ID {$message->orderId}");
return $handler($message);
});
Custom Serializers Override the default JSON serializer:
PServiceBus::setSerializer(new CustomSerializer());
Implement Gdx\PServiceBus\Serializers\SerializerInterface.
Dynamic Handlers Register handlers dynamically at
How can I help you explore Laravel packages today?