--- title: "Consuming messages" description: "Consuming messages — PHP / Laravel BabelQueue driver (1.x)." source: https://babelqueue.com/docs/laravel/1.x/consuming-messages/ updated: 2026-06-06T00:00:00.000Z --- # 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 ```php // 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: ```php 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: ```bash 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](/docs/laravel/1.x/configuration/). That's the whole loop: any producer, any consumer, one schema.