Consuming messages
Consumers route on the URN. Map each URN to a handler class in
config/babelqueue.php, then process the worker as usual.
Register the handler
// config/babelqueue.php
return [
'handlers' => [
'urn:babel:orders:created' => App\Babel\Handlers\OrderCreatedHandler::class,
],
'on_unknown_urn' => 'dead_letter',
];
Write the handler
A handler receives the decoded data, the meta block and the message’s
trace_id for cross-service correlation. Implement the optional failed() hook
to react when processing throws:
namespace App\Babel\Handlers;
final class OrderCreatedHandler
{
public function handle(array $data, array $meta, string $traceId): void
{
logger()->withContext(['trace_id' => $traceId])
->info('Order received', $data);
// ... your business logic
}
public function failed(array $data, ?\Throwable $e): void
{
report($e);
}
}
Run the worker
BabelQueue is a drop-in Laravel queue driver, so you consume with the standard worker — just point it at your polyglot connection:
php artisan queue:work babelqueue
The $traceId ties this consumer’s logs back to the original producer and to
every other service that handled the same job — no matter which language emitted
it. Exhausted retries and unknown URNs follow your on_unknown_urn /
dead_letter policy from Configuration.
That’s the whole loop: any producer, any consumer, one schema.