mhsaheb / laravel-rpc-rabbitmq
Request/Reply (RPC) over RabbitMQ for Laravel, using direct-reply-to.
Installs: 5
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/mhsaheb/laravel-rpc-rabbitmq
Requires
- php: >=8.1
- php-amqplib/php-amqplib: ^3.5
This package is auto-updated.
Last update: 2025-11-13 12:28:01 UTC
README
A simple Request/Reply (RPC) layer for Laravel microservices over RabbitMQ, built on top of php-amqplib.
It lets your Laravel services call each other synchronously (like a local function) without HTTP.
Features
- π Works with RabbitMQ (supports direct-reply-to for low-latency RPC)
- β» Reuses your existing
queue.connections.rabbitmqconfig (compatible withvladimir-yuldashev/laravel-queue-rabbitmq) - β± Built-in timeouts, retries, and circuit breaker
- π¦ Easy route registration (via config, routes file, or CLI)
- π Pass arbitrary payload arrays between services
- π‘ Supports meta info for request tracing or auth
Installation
1) Require the package
composer require mhsaheb/laravel-rpc-rabbitmq
2) Publish the config
php artisan vendor:publish --provider="RabbitRPC\\RpcServiceProvider" --tag=config
This will create config/rpc.php.
Configuration
Edit .env in each service:
# Map logical endpoints to queues RPC_SERVICE1_QUEUE=service-1-queue RPC_SERVICE2_QUEUE=service-2-queue # Client defaults RPC_TIMEOUT=3 RPC_RETRIES=0 RPC_RETRY_DELAY_MS=100 # Circuit breaker RPC_CB_FAILS=5 RPC_CB_OPEN_SEC=15
And in config/rpc.php you can map endpoints and routes:
return [ 'endpoints' => [ 'service-1' => env('RPC_SERVICE1_QUEUE', 'service-1-queue'), 'service-2' => env('RPC_SERVICE2_QUEUE', 'service-2-queue'), ], 'timeout_seconds' => (float) env('RPC_TIMEOUT', 3.0), 'retries' => (int) env('RPC_RETRIES', 0), 'retry_delay_ms' => (int) env('RPC_RETRY_DELAY_MS', 100), 'cb' => [ 'failure_threshold' => (int) env('RPC_CB_FAILS', 5), 'open_seconds' => (int) env('RPC_CB_OPEN_SEC', 15), ], 'routes' => [ 'service-1' => [ // 'service-1.create' => 'MyService@create', // 'service-1.getProfile' => 'MyService@getProfile', ], 'service-2' => [ //'service-2.submit' =>'MyService@submit', ], ], ];
Defining RPC Routes
Option 1 β Config map
Add to config/rpc.php under 'routes'.
Option 2 β Per-endpoint routes file
Create routes/rpc_user.php:
use App\\Services\\UserService; return [ 'user.create' => UserService::class.'@create', 'user.getProfile' => UserService::class.'@getProfile', ];
Option 3 β CLI flag
php artisan rpc:consume user --route="user.create=App\\Services\\UserService@create"
Running the Responder
A responder listens on a queue for requests and returns a reply.
Example: In user_service, to expose user.create:
php artisan rpc:consume user
This will load all routes for user from config or routes/rpc_user.php.
Your handler method:
namespace App\\Services; class UserService { public function create(array $params): array { // $params = ['name' => ..., 'email' => ...] $user = User::create([ 'name' => $params['name'], 'email' => $params['email'], 'phone' => $params['phone'] ?? null, 'password' => bcrypt('secret'), ]); return $user->toArray(); } }
Calling Another Service
From accelerator_service, call user.create on the user_service:
use RabbitRPC\\Facades\\Rpc; // or DI via RabbitRPC\\Contracts\\Client Route::post('/provision-user', function (Request $request) { $payload = $request->only('name', 'email', 'phone'); $user = Rpc::call('user', 'user.create', $payload); return response()->json([ 'created' => true, 'user' => $user, ]); });
Payload & Meta
The call() method signature:
Rpc::call(string $endpoint, string $route, array $payload = [], ?float $timeoutSeconds = null): array
$endpointβ logical key fromconfig/rpc.php(user,accelerator, etc.)$routeβ route string that matches the responderβs handler$payloadβ associative array of data to pass$timeoutSecondsβ optional per-call override
The responder receives:
function (array $payload, array $meta) { ... }
$meta contains info like request_id, app, ts.
Health Check
Every responder auto-registers a ping route:
php artisan tinker >>> Rpc::call('user', 'ping'); # ['ok' => true, 'endpoint' => 'user', 'at' => '2025-08-13T11:00:00Z']
Supervising
In production, run responders under Supervisor or systemd:
supervisor.conf
[program:rpc-user]
command=php artisan rpc:consume user
numprocs=1
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/var/log/rpc-user.log
Advanced
- Per-route timeouts/retries: Extend
RpcClientto look up route-specific settings. - Idempotency: Store
meta.request_idon side-effecting routes to avoid duplicates. - Security: Check
$metafor a service token in each handler.
License
MIT