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

Intercall Laravel Package

deployteam/intercall

deployteam/intercall is a lightweight Laravel package for handling inter-service calls with a clean, fluent API. Configure endpoints, attach middleware, and keep communication between your applications consistent, predictable, and easy to test.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a framework-agnostic package, so treat it as a raw library rather than a Laravel package: there is no service provider, no facade, and no config publish step you can rely on. Budget 30–60 minutes for a source read before writing any application code.

Minimal steps to first message:

  1. composer require deployteam/intercall and immediately pin it ("deployteam/intercall": "x.y.z" exact) — see the vendor-risk note below.
  2. Read, in this order: composer.json (PHP constraint, PSR-4 root namespace), src/ top level for the contract interfaces (typically an event/message value object, a dispatcher/publisher, and a transport/driver interface), then the README example and tests/.
  3. Register the pieces yourself in AppServiceProvider::register() (or a small IntercallServiceProvider in app/Providers) and bind the transport interface to a concrete driver chosen by env:
$this->app->singleton(Transport::class, fn ($app) => match (config('intercall.transport')) {
    'redis' => new RedisTransport(config('intercall.redis')),
    default => new InMemoryTransport(), // dev + tests
});
  1. Add config/intercall.php with the transport DSN, a default source/system name, and an event-name map. Only read it via config(), never env(), so config:cache stays safe.

First use case worth wiring up: one outbound event from your Laravel app to one other system — e.g. publish order.placed from your checkout flow so a billing service can react. Keep it one-way and fire-and-forget for the first iteration; add consumption once you trust the delivery semantics.

Implementation Patterns

Publish from a queued, after-commit listener. The package is transport-agnostic and knows nothing about your database transaction. Never publish inline inside a DB transaction — the event can escape before commit (or survive a rollback). Bridge from Laravel's own events instead:

class PublishOrderPlaced implements ShouldQueue, ShouldHandleEventsAfterCommit
{
    public function handle(OrderPlaced $event): void
    {
        $this->intercall->dispatch(new SystemEvent(
            name: 'order.placed.v1',
            payload: ['order_id' => $event->order->id, 'total' => $event->order->total_cents],
            meta: ['correlation_id' => $event->correlationId],
        ));
    }
}

Keep the package behind your own thin port. Define App\Contracts\EventBus with publish(string $name, array $payload, array $meta = []) and implement it with intercall. Every call site depends on your interface, not on the package. This is the single highest-value pattern here: it makes the dependency replaceable if the package stalls and gives you one place to add logging, retry, and correlation IDs.

Payloads as flat arrays/DTOs, versioned names. Serialize to scalars only: IDs, ISO-8601 strings, integer minor units. Do not put Eloquent models, Carbon instances, enums (unless you control the PHP version on both ends), or lazy-loading relations into the envelope. Encode the schema version in the event name (order.placed.v1) and treat a breaking payload change as a new name rather than an in-place edit.

Consumer as a long-running Artisan command. Since there is no queue integration, you own the loop:

class ConsumeIntercall extends Command
{
    protected $signature = 'intercall:consume {--once}';

    public function handle(Listener $listener): int
    {
        $listener->subscribe($this->handlers());   // name => callable/class
        $this->option('once') ? $listener->tick() : $listener->run();
        return self::SUCCESS;
    }
}

Run under Supervisor with --once in a cron loop if you'd rather not manage long-lived processes. Prefer --once + cron for low volume; use the blocking loop for high volume. Either way, dispatch each inbound message to a Laravel job so you inherit retries, backoff, and failed_jobs rather than reimplementing them.

Map inbound events to Laravel events, not to logic. A single EventReceived job that resolves a handler class from a config map keeps routing declarative:

'handlers' => [
    'invoice.paid.v1' => \App\Intercall\Handlers\MarkOrderPaid::class,
],

Test with the in-memory transport. Bind a fake in TestCase::setUp and assert on the recorded envelopes — publish assertions are far cheaper than standing up a broker in CI. For integration coverage, run the real transport in a single dedicated test suite, not the whole suite.

Transport swap by environment. sync/in-memory locally, the real broker in staging/prod. If the package's local transport records rather than delivers, add one docker-compose service for the broker so staging exercises real serialization.

Gotchas and Tips

  • Vendor risk is the headline. Zero stars, zero dependents, and a "last release" date of 2026-10-21 — a future date, which almost certainly means a mistagged release or a Packagist artifact rather than a real one. Verify with composer show deployteam/intercall and git tag before trusting the version constraint. Pin exact, commit composer.lock, and keep the anti-corruption layer described above. Have a fallback plan (Symfony Messenger, Laravel's queue + a broker, or plain HTTP webhooks).
  • Read the release history before the README. With no community, the changelog is the documentation. Also check the PHP constraint and required extensions (ext-json, possibly ext-redis/ext-sockets) against your runtime — a mismatch surfaces at runtime, not install time.
  • "Framework-agnostic" means you own the operational surface: worker supervision, graceful shutdown (SIGTERM handling so in-flight messages aren't dropped), dead-letter handling, retry counts, backoff, and observability. Assume at-least-once delivery until the source proves otherwise; make every handler idempotent with a dedupe key (event ID or a natural key like order_id + name + version).
  • Long-running consumer leaks. If you use the blocking loop, watch memory (log memory_get_peak_usage per N messages), and be aware Laravel keeps DB connections and model state alive across iterations. DB::purge() periodically or use --once cron mode. Under Octane, never resolve the listener as a singleton if it caches per-request state.
  • Serialization drift is the classic failure. A producer sending {"total": "19.99"} and a consumer expecting 1999 fails silently-ish and late. Write one test that asserts the exact JSON envelope shape, and validate inbound payloads against a schema in the handler before touching your domain.
  • Debug at the transport boundary. Log the full envelope (name, ID, correlation ID, attempt) in your port implementation, not inside handlers. Propagate a correlation ID generated at the HTTP request and carry it in the envelope meta — without it, tracing a cross-system flow is guesswork.
  • Watch for dispatch loops. If you both listen to Laravel events and re-emit inbound intercall events, an event that round-trips can echo. Add a source field to the envelope and drop messages whose source matches your own.
  • Extension points to check first when you hit a wall: the transport interface (write your own driver — often easier than bending a stock one), the serializer/codec hook, and the event-name resolver. These are usually the intended seams in a package of this shape; anything beyond that means forking, which is a strong signal to reconsider the dependency.
  • Config quirks: with no published config, you're authoring config/intercall.php yourself — keep it env-free inside the file, and rebuild caches (php artisan config:cache) in deploy since the package may read config only at construction time.
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.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core