
Spoolrail
Introduction
Section titled “Introduction”Spoolrail lets Laravel applications exchange messages through a broker.
Message brokers let different apps communicate without being directly connected. One app sends a message, the broker holds it, and another app picks it up later. Think of it like leaving a note for your coworker instead of waiting around to tell them in person.
This prevents the brittleness of direct HTTP calls, where one app has to wait for the other. So, whether the receiving app is offline or the system is overwhelmed by a sudden spike in traffic, messages wait safely for each subscription until its application is ready to process them.
Message brokers are common in microservices and service-oriented architectures to handle async communication and keep things loosely coupled.
Message processing in a Laravel queue
Section titled “Message processing in a Laravel queue”Publishing applications send messages to topics. Spoolrail uses fanout delivery so every application subscribed to a topic gets its own copy. Spoolrail hands each copy to the Laravel queue selected by the receiving application’s subscription.
This handoff separates broker delivery from handler execution. After Laravel queue accepts the message, it owns handler execution, retries, and failure.
Delivery Guarantees
Section titled “Delivery Guarantees”By default, Spoolrail delivers every published message once and in order to each subscription’s Laravel queue. This guarantee covers ordinary publication and broker redeliveries.
Some drivers let you disable one or more guarantees to raise the throughput limit. Read more about delivery guarantees.
Package Goals
Section titled “Package Goals”Message broker systems are powerful, but that power can lead to complexity. There are no plans to chase every feature or configuration knob across drivers with this package.
The goal is to focus on what’s essential for every broker implementation, delivering an elegant, driver-agnostic, and delightful API — even if that means leaving some bells and whistles behind.
Supported Drivers
Section titled “Supported Drivers”- 🐇 RabbitMQ
- 📦 AWS SNS/SQS
- ☁️ Google Pub/Sub
Quick Start
Section titled “Quick Start”1. Install the Package
Section titled “1. Install the Package”composer require spoolrail/spoolrail2. Publish Spoolrail Files
Section titled “2. Publish Spoolrail Files”php artisan spoolrail:installThe installer publishes config/spoolrail.php and creates routes/subscriptions.php.
3. Set an Ownership Prefix
Section titled “3. Set an Ownership Prefix”Set a stable ownership prefix for the app in .env. The ownership prefix distinguishes this application’s subscriptions from subscriptions owned by other applications:
SPOOLRAIL_PREFIX=warehouse4. Configure a Driver
Section titled “4. Configure a Driver”Choose a driver below.
Install the RabbitMQ client:
composer require php-amqplib/php-amqplib:^3.7.4Select the RabbitMQ connection and configure the broker in .env:
SPOOLRAIL_CONNECTION=rabbitmq
RABBITMQ_HOST=127.0.0.1RABBITMQ_USERNAME=spoolrailRABBITMQ_PASSWORD=secretRABBITMQ_VHOST=spoolrail
RABBITMQ_MANAGEMENT_URL=http://127.0.0.1:15672This walkthrough requires RabbitMQ 4.3 or later with the Management plugin enabled. See the RabbitMQ driver guide for TLS and other connection settings.
Install the AWS SDK:
composer require aws/aws-sdk-php:^3.392.0Select the AWS SNS/SQS connection and configure the account in .env:
SPOOLRAIL_CONNECTION=snssqs
AWS_ACCESS_KEY_ID=<your-key-id>AWS_SECRET_ACCESS_KEY=<your-secret-access-key>AWS_DEFAULT_REGION=us-east-1AWS_ACCOUNT_ID=<your-account-id>See the AWS SNS/SQS driver guide for required IAM permissions or when the application uses temporary credentials, an IAM role, or a compatible local service.
Install the Google Cloud Pub/Sub client:
composer require google/cloud-pubsub:^2.20.0Select the Google Pub/Sub connection and configure the project in .env:
SPOOLRAIL_CONNECTION=pubsub
GOOGLE_CLOUD_PROJECT=warehouse-productionSPOOLRAIL_GOOGLE_CREDENTIALS=/run/secrets/warehouse-pubsub.jsonSPOOLRAIL_GOOGLE_PUBSUB_ENDPOINT=europe-west1-pubsub.googleapis.com:443See the Google Pub/Sub driver guide for required IAM permissions, Application Default Credentials, or the global endpoint.
5. Create a Handler
Section titled “5. Create a Handler”You can use make:handler to scaffold the class:
<?php
namespace App\Messages;
use App\Services\Inventory;use Spoolrail\Spoolrail\Contracts\MessageHandler;use Spoolrail\Spoolrail\Message;
class ReserveInventoryHandler implements MessageHandler{ public function __construct( private readonly Inventory $inventory, ) {}
public function handle(Message $message): void { $this->inventory->reserve( (int) $message->payload['order_id'], ); }}6. Declare a Subscription
Section titled “6. Declare a Subscription”Add the subscription to routes/subscriptions.php:
<?php
use App\Messages\ReserveInventoryHandler;use Spoolrail\Spoolrail\Facades\Spoolrail;
Spoolrail::subscribe( topic: 'orders', name: 'warehouse-orders', handler: ReserveInventoryHandler::class,);Spoolrail loads this file automatically.
7. Create the Broker Resources
Section titled “7. Create the Broker Resources”php artisan spoolrail:ensure-topologyRun this command during deployment whenever subscription declarations change.
8. Start the Workers
Section titled “8. Start the Workers”Run consumers for every subscription on the default Spoolrail connection:
php artisan spoolrailMake sure Laravel queue workers are running for the connections and queues selected by your subscriptions.
9. Publish a Message
Section titled “9. Publish a Message”use Spoolrail\Spoolrail\Facades\Spoolrail;use Spoolrail\Spoolrail\Message;
$published = Spoolrail::publish( 'orders', Message::make('order.created', [ 'order_id' => $order->id, ]),);The returned message contains the UUID and UTC publication time that subscribers receive.
