--- title: "Producing messages" description: "Producing messages — implement PolyglotMessage and dispatch through Symfony Messenger; BabelQueue encodes the canonical envelope." source: https://babelqueue.com/docs/symfony/1.x/producing-messages/ updated: 2026-06-07T00:00:00.000Z --- # Producing messages Producing is a normal Messenger dispatch. The only requirement is that your message implements `BabelQueue\Symfony\Contracts\PolyglotMessage`, which tells the serializer its URN and how to turn it into the pure-JSON `data` payload. ## Define a message ```php use BabelQueue\Symfony\Contracts\PolyglotMessage; final class OrderCreated implements PolyglotMessage { public function __construct(public int $orderId) {} public function getBabelUrn(): string { return 'urn:babel:orders:created'; } public function toPayload(): array { return ['order_id' => $this->orderId]; } public static function fromBabelPayload(array $data): static { return new self((int) $data['order_id']); } } ``` - `getBabelUrn()` — the message's [URN](/docs/spec/1.x/urn/) identity on the wire. - `toPayload()` — the pure, JSON-encodable `data` (no PHP objects; see the [data rules](/docs/spec/1.x/envelope/#cross-language-data-rules)). - `fromBabelPayload()` — rebuilds the message from an inbound envelope on consume. ## Dispatch ```php // a normal Messenger dispatch $bus->dispatch(new OrderCreated(1042)); ``` On the wire it becomes the canonical envelope — readable by every BabelQueue SDK: ```json { "job": "urn:babel:orders:created", "trace_id": "…", "data": { "order_id": 1042 }, "meta": { "id": "…", "queue": "orders", "lang": "php", "schema_version": 1, "created_at": 1749132727000 }, "attempts": 0 } ``` `trace_id` is stamped automatically. If you dispatch while handling another BabelQueue message (with the trace middleware enabled), the new message **inherits** the inbound `trace_id`. Next: [Consuming messages](/docs/symfony/1.x/consuming-messages/).