jasuwienas/message
A small Laravel/PHP package for handling application messages, offering a simple, conventions-friendly API to define and manage message content. It makes adding lightweight messaging support to your project quick and straightforward.
Reality check before you install anything. This is a Symfony 3 bundle, not a Laravel package. Its last release was 2018-11-26, Symfony 3 reached end-of-life in January 2021, and the package has zero stars and zero dependents. There is no Laravel service provider, no facade, and no config file you can publish with php artisan vendor:publish. A Laravel developer's "first use case" is therefore almost never installing it — it is reading it as a reference implementation and, if you must, maintaining it inside a legacy Symfony 3 app.
Where to look first (in this order):
composer.json — check the require block for the Symfony version constraint, PHP constraint, and which transport libraries (AMQP, Redis, etc.) it actually depends on. This tells you immediately whether it can coexist with anything you run today.README.md — the only documentation you will get. Expect a bundle registration snippet and a YAML config example.src/ — locate the message abstraction (a message interface/DTO), the producer/publisher, and the consumer/handler. Those three are the whole package.Resources/config/ — the DI service definitions. This is where the wiring lives and where you'd fork.tests/ — with zero dependents, tests are your only spec for edge-case behavior.Minimal steps if you genuinely must run it (legacy Symfony 3 host):
composer require jasuwienas/message
app/AppKernel.php inside registerBundles().app/config/config.yml (transport DSN / queue name).src/Command/ or the README) under Supervisor.If you are on Laravel, the first useful use case is a port, not an install: take the package's producer/consumer split and reimplement it with php artisan make:job plus dispatch() and php artisan queue:work. That is roughly an afternoon of work and removes the dependency entirely.
The package's design is the standard three-part shape, and it maps cleanly onto Laravel's queue. Once you see the mapping, you can decide whether to port or bridge.
Concept in jasuwienas/message |
Laravel equivalent |
|---|---|
| Message DTO (serializable payload) | app/Jobs/*.php class with public typed properties |
| Producer / publisher | dispatch(new MyJob($payload)) |
| Consumer / handler, tagged in DI | handle() method on the job, executed by queue:work |
| Transport config in YAML | config/queue.php connections |
| Bundle compiler pass collecting handlers | Laravel's container auto-resolution + ShouldQueue |
| Worker daemon / process manager command | queue:work under Supervisor, or Horizon |
Pattern 1 — Message as a thin DTO. Keep the message object to scalars and IDs. Fetch entities inside the handler. This is the single most important habit whether you're using this bundle or Laravel jobs, because it keeps messages small, serializable, and replayable.
Pattern 2 — One handler per message type. The bundle resolves handlers via DI tags; that means a message with two handlers either double-processes or silently picks one depending on the resolver. In Laravel this maps to one job class per intent. If you need fan-out, publish N distinct messages rather than one message with N handlers.
Pattern 3 — Producer in the web request, consumer out of process. Dispatch after the DB transaction commits. In the Symfony bundle that means enqueueing at the end of the controller/service method, never mid-transaction. In Laravel use DB::afterCommit() or dispatch from an event fired post-commit. This is the bug that bites hardest and it is framework-agnostic.
Pattern 4 — Bridging two apps over one broker. The realistic modern use of this package: a legacy Symfony 3 service stays the producer, and a new Laravel service becomes the consumer on the same AMQP/Redis queue. That works only if you freeze the message contract — a documented JSON schema, not PHP serialize(). Write the contract down before either side ships, and version it.
Pattern 5 — Handler idempotency. Design every handler to tolerate redelivery: upsert instead of insert, guard with a processed-message table or a unique constraint. Since the package predates modern retry/dead-letter tooling, expect at-least-once delivery and no built-in dedupe.
Workflow tip: log at exactly two boundaries — on publish (message type, ID, correlation ID) and on handler entry/exit (same ID, duration, outcome). With no community and no observability hooks, these logs are your only debugging surface.
It is abandoned, and that is the headline. No security patches, no Symfony 4/5/6 container compatibility, almost certainly no PHP 8 support. The Symfony 3 bundle system (AppKernel, Resources/config/*.yml) was replaced twice over. Do not attempt to install this into a modern Laravel or Symfony app; Composer will fail on constraints or, worse, succeed and break at runtime.
Zero dependents means zero field reports. Nobody has hit the bugs before you. Treat src/ as the specification, not the README. If you adopt it, vendor it or fork it immediately — pin the exact commit in composer.json and assume upstream will never move.
Don't mix worker runtimes on one queue without a contract. A Symfony 3 consumer and a Laravel queue:work process reading the same Redis/AMQP queue will happily eat each other's payloads. Use separate queues, or a strict shared JSON envelope with an explicit type field.
Serialization is the classic failure. If the package uses PHP serialize(), messages become unreadable across PHP versions, class renames, or framework swaps. Convert the boundary to JSON on day one, even if it means a custom serializer — the bundle's transport layer is the intended extension point for exactly this.
Config quirks you'll hit in the legacy host: bundle registration order in AppKernel, parameters that must live in parameters.yml rather than the bundle's own config, and handler services that are never instantiated because the tag name doesn't match the compiler pass. When a message "disappears," check the tag before you check the broker.
Debugging order of operations: (1) confirm the message reached the broker — inspect the queue directly with rabbitmqctl/redis-cli; (2) confirm a worker is consuming — check Supervisor status and worker logs; (3) confirm the handler resolved — add a log line at the top of handle(); (4) only then look at business logic. Most "lost message" reports fail at step 1 or 3.
Extension points worth knowing: the transport/publisher binding (swap the broker), the serializer (swap to JSON), and the handler tag name (rename to fit your container conventions). Those three cover nearly every fork you'd need.
Restart workers on deploy. Long-running consumers hold stale code in memory. Laravel gives you queue:restart; with this bundle you need to bounce Supervisor manually — build that into your deploy script from the start.
Recommendation for a Laravel developer day-to-day: do not add this dependency. Use Laravel's native queue (database or redis driver, Supervisor in production, Horizon if you want the dashboard). Reach for this package only when you are contracted to maintain an existing Symfony 3 service, and even then budget for replacing it — the EOL risk is larger than the migration cost.
How can I help you explore Laravel packages today?