Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Distributed Architecture Laravel Package

giudicelli/distributed-architecture

A Laravel/PHP package for building distributed applications, providing conventions and utilities to organize service boundaries, messaging, and shared architectural concerns so teams can structure scalable systems with clearer, maintainable distributed logic.

View on GitHub
Deep Wiki
Context7

Getting Started

This repository is best treated as reference material, not a drop-in package. It has no stars, no dependents, and no Packagist-style install path worth trusting in production — so the first step is verifying what you actually have before wiring it into an app.

Minimal steps:

  1. Clone and read the tree first. Run git clone and inspect the top-level directories (src/, tests/, composer.json, any docs/). Look for a composer.json autoload block — that tells you the namespace and whether it's PSR-4 structured as a reusable library or just an example app.
  2. Check the composer.json require block. If it pulls laravel/framework or illuminate/*, it's Laravel-oriented; if it only requires php and a few small libs (e.g. a message bus, UUID lib), it's framework-agnostic and you'll need to write your own service provider.
  3. Look for a service provider. Search for *ServiceProvider.php. If none exists, expect to register bindings manually in config/app.php or your own provider.
  4. Run the tests. composer install && vendor/bin/phpunit (or pest). This is the fastest way to understand intended behavior — the tests are the de-facto documentation for repos of this size.
  5. First use case: pick the smallest domain concept in the repo (usually an event bus or command bus, or a message producer/consumer pair) and reproduce it in isolation in a fresh Laravel app via php artisan make:command. Don't try to adopt the whole architecture at once — it's almost certainly a demo of multiple patterns (CQRS, event sourcing, sagas, outbox) cobbled together.

Where to look first: README.md (often sparse), then src/ for interfaces — interfaces reveal the contract, and contracts are what you actually reimplement.

Implementation Patterns

Because this is a pattern-reference repo rather than a batteries-included package, "usage" means adapting the pattern, not calling the API. The realistic day-to-day patterns:

1. Command/Query bus pattern. If the repo exposes a CommandBus/QueryBus, wrap it behind a Laravel container binding:

// AppServiceProvider::register()
$this->app->singleton(CommandBus::class, fn ($app) =>
    new InMemoryCommandBus($app)
);

Then resolve via constructor injection — never app(CommandBus::class) inside services, or you'll lose testability.

2. Event bus for domain events. The typical pattern here is publishing domain events (OrderPlaced, PaymentCaptured) and dispatching handlers. In Laravel, bridge to Illuminate\Contracts\Events\Dispatcher rather than maintaining a separate event registry:

class DomainEventPublisher
{
    public function __construct(private Dispatcher $events) {}

    public function publish(object $event): void
    {
        $this->events->dispatch($event);
    }
}

This gets you Laravel's queue integration (ShouldQueue listeners) for free, which is usually better than the repo's hand-rolled bus.

3. Outbox pattern for reliable messaging. If the repo demonstrates transactional outbox (write event to DB in same transaction as aggregate, then a worker publishes), keep that idea but implement it with an Eloquent model + a queued job:

DB::transaction(function () use ($order) {
    $order->save();
    OutboxMessage::create([
        'type' => 'order.placed',
        'payload' => $order->toArray(),
    ]);
});

A scheduled php artisan outbox:relay command then publishes and marks rows sent. This is the single most valuable pattern in repos like this — most developer "distributed architecture" mistakes are dual-write bugs.

4. Sagas / process managers. If the repo models a saga (e.g. order → payment → stock), map it to a Laravel state machine table on the process aggregate. Persist saga state, listen for completion events, emit the next command. Prefer this over chained jobs, because chained jobs have no durable state.

5. Integration tips.

  • Add the repo's namespace to composer.json "autoload": {"psr-4": {"Giudicelli\\DistributedArchitecture\\": "packages/giudicelli/src/"}} if you must keep it vendored.
  • Wrap every repo class in an anti-corruption layer (your own interface) so you can swap it for a mature library later.
  • Write integration tests against a real DB (SQLite in-memory won't test transactional behavior correctly if you rely on row locks).

Gotchas and Tips

No version constraint / abandoned risk. Zero dependents means no one has battle-tested this against current Laravel versions (10/11/12). Pin the source in composer.lock or path repository if you vendor it; don't assume composer require giudicelli/distributed-architecture resolves to anything.

Namespace mismatch is the #1 first bug. Repos made as course demos often hardcode App\ namespaces or don't declare an autoload block correctly. If composer dump-autoload -o doesn't resolve classes, check the psr-4 mapping against actual directory depth.

Transaction boundaries. Almost every distributed-architecture demo assumes the outbox event and the aggregate save are in one transaction. In Laravel, DB::transaction() closes at the callback return — if you dispatch() an event inside that closure and a queued listener fires synchronously (afterCommit = false), you'll process an event for a rolled-back write. Set:

// In a queued listener
public bool $afterCommit = true;

or override the event dispatcher's dispatchAfterResponse.

Idempotency. If the repo shows consumer logic, it almost certainly doesn't deduplicate messages. Add a processed_messages table keyed by message ID with a unique index, and wrap handler execution in insertOrIgnore — without this, retries from your queue will double-process anything money-related.

Clock/timezone assumptions. Event-sourced demos love new DateTimeImmutable() at the call site. Inject Clock (or Illuminate\Support\Carbon::now()) so your tests aren't flaky and your replayable event history is reproducible.

Debugging distributed flows. Enable Laravel Telescope or Horizon for queues, and add a correlation ID to every command/event:

$payload['correlation_id'] = (string) Str::uuid();

Thread it through handlers — you cannot debug async flows without it.

Extension points. The repo's interfaces (if any) are the seam you should exploit. Wrap its EventBus, MessageProducer, etc. behind your own interfaces and bind implementations in a service provider. That way, when you outgrow it — which you will — you swap the binding for a mature library:

  • Event sourcing: spatie/laravel-event-sourcing
  • CQRS buses: laravel/framework's own dispatch + laravel/horizon for reliability
  • Sagas: spatie/laravel-event-sourcing process managers, or a hand-rolled state table
  • Outbox: no canonical Laravel package; implement as shown above

Config quirks. Watch for env var names that collide with your own (e.g. QUEUE_CONNECTION, EVENT_BUS_DRIVER) — if the repo publishes a config file, namespace keys under distributed.* and document them in .env.example. Check for hardcoded connection names (mysql, redis) in fixtures/tests.

Verdict. Use this as a reading exercise to internalize outbox, CQRS, and saga patterns, then implement them with Laravel primitives (DB::transaction, ShouldQueue, afterCommit) rather than depending on the package directly. That gives you 90% of the architectural value with 0% of the supply-chain risk.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log