telephantast/message-bus
Telephantast Message Bus is a lightweight Laravel package for dispatching messages to dedicated handlers. It supports command and query handling with middleware, helping you build clean, decoupled, and testable PHP applications.
telephantast/message-bus is a small, low-ceremony message bus abstraction (message → handler dispatch with middleware support). With only 19 stars and an unknown repository link, treat the source as the primary documentation.
Minimal integration:
composer require telephantast/message-bus
src/ first. The package is small enough that the interfaces (MessageBus, Message, Middleware, likely a MessageHandler contract) are the whole story. Look for a facade/service provider and check whether handlers are resolved through the Laravel container by class-string or by interface binding.extra.laravel.providers). If not auto-discovered, add it to bootstrap/providers.php.Message DTO, a handler class with a __invoke (or handle) method, and dispatch through the injected MessageBus. This replaces fat controllers and keeps transactional/queue logic out of HTTP code.final class RegisterUser implements \Telephantast\MessageBus\Message {
public function __construct(public readonly string $email) {}
}
final class RegisterUserHandler {
public function __invoke(RegisterUser $message, UserRepository $users): User {
return $users->create($message->email);
}
}
// In a controller / action
public function __invoke(RegisterUserRequest $request, MessageBus $bus): UserResource
{
return UserResource::make($bus->dispatch(new RegisterUser($request->email)));
}
If the package does not ship a facade, inject the MessageBus interface via the container. Verify the binding name once — it is the single most important detail to confirm before building on top of this package.
CommandBus/QueryBus interfaces), lean into that; otherwise split by convention and naming.DB::transaction(...) wrapping command handlers, validation, logging with correlation IDs, and metrics. Order matters — register transaction middleware innermost (after validation) so retries don't re-open transactions unnecessarily.app()->make($handlerClass) to resolve the handler. That means any Laravel injection pattern works inside handlers: repositories, Http client, cache, filesystem — no extra wiring needed.ShouldQueue-style interface or a QueueMiddleware), dispatch long-running work through the bus from HTTP code and let the bus handle serialization. If not, wrap the dispatch in a Job and keep the bus synchronous.CommandBus service you control, e.g. App\Bus\CommandBus delegating to the package. This lets you swap the underlying implementation later, mock it in tests, and add app-specific middleware without forking. It is the single highest-value integration tip for a 19-star package.Event system rather than replacing it — the bus handles the handler pipeline, Laravel events handle observers and broadcast notifications.DB::transaction is a no-op, so this is safe).composer.json, src/, and any tests/ before committing. Lock the version in composer.json to something specific ("^1.0" rather than "*") so a minor release doesn't change middleware contract semantics.dispatch() as mixed. Add your own typed wrappers (CommandBus::dispatch(Message): void, QueryBus::fetch(Query): mixed) so PHPStan/Psalm stay useful. Without this, generic handlers silently widen return types.[Logging, Metrics, Validation, Transaction, Retry] from outside in, with retry placed to wrap the transactional unit deliberately.SerializesModels-compatible. Avoid carrying Eloquent models across async boundaries without SerializesModels; prefer IDs. If the package uses serialize() directly, closures and container-resolved objects will break.TracingMiddleware that logs message class → handler class → duration. Because the bus hides dispatch behind one call, stack traces are less useful than a trace list of which messages ran and which middleware fired.class TracedBus implements MessageBus) and bind that in a service provider.Illuminate\Bus wrapper is a one-file change instead of a refactor.How can I help you explore Laravel packages today?