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

Humus Amqp Bundle Laravel Package

genhoi/humus-amqp-bundle

genhoi/humus-amqp-bundle brings AMQP messaging to PHP apps, with straightforward configuration for RabbitMQ producers and consumers so you can publish and process messages with minimal boilerplate.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Symfony bundle, not a Laravel package. There is no service provider, no Laravel auto-discovery, and no config/humus_amqp.php. A Laravel app cannot composer require this and expect it to work — the assessment below is written for a Laravel developer who either (a) is being pulled into a Symfony codebase that already depends on it, or (b) wants to mine its DI/topology patterns for a Laravel AMQP integration. For greenfield Laravel work, use vladimir-yuldashev/laravel-queue-rabbitmq (built on php-amqplib) instead; the runtime model is different and not interchangeable.

Minimal setup (Symfony host app)

  1. Install the C extension first — this package wraps ext-amqp, not php-amqplib:
    pecl install amqp && docker-php-ext-enable amqp
    
  2. composer require genhoi/humus-amqp-bundle (it pulls prolic/humus-amqp). v2.3.0 adds Symfony 7 component constraints, so on a Symfony 6.4/7.x host you should land on the current tag; on older hosts (5.4) Composer will resolve back to a pre-2.3 tag — check composer show genhoi/humus-amqp-bundle after install and read the schema for that version.
  3. Register the bundle in config/bundles.php:
    Genhoi\HumusAmqpBundle\HumusAmqpBundle::class => ['all' => true],
    
  4. Write config/packages/humus_amqp.yaml (schema below).
  5. Run a worker: bin/console humus:consume <consumer_id> — confirm the exact command name with bin/console list humus, since the CLI is registered by the bundle and is thin.

Where to look first

Because adoption is essentially zero (single-digit stars, no known dependents), the docs are not the source of truth — the code is:

Look at Why
vendor/genhoi/humus-amqp-bundle/DependencyInjection/Configuration.php The exact config schema for the version you pinned. Every key below must be verified there.
vendor/genhoi/humus-amqp-bundle/Resources/config/*.xml (or .php) Service ids, tags, and the console command registration.
vendor/prolic/humus-amqp/docs/ Runtime semantics: Producer, Consumer, Envelope, ConsumerManager.

First use case: publish → consume

# config/packages/humus_amqp.yaml
humus_amqp:
    connections:
        default:
            host: '%env(RABBITMQ_HOST)%'
            port: 5672
            login: '%env(RABBITMQ_USER)%'
            password: '%env(RABBITMQ_PASSWORD)%'
            vhost: /
    exchanges:
        orders:
            name: orders
            type: topic
            connection: default
    queues:
        order_created:
            name: order_created
            connection: default
            exchange: orders
            routing_keys: ['order.created']
    producers:
        order_publisher:
            class: Humus\Amqp\Producer
            exchange: orders
            connection: default
    consumers:
        order_created_consumer:
            class: Humus\Amqp\Consumer
            queue: order_created
            connection: default
            callback: App\Amqp\OrderCreatedHandler

Then bin/console humus:consume order_created_consumer. That is the whole day-one loop.

Implementation Patterns

1. Topology lives in config; code references ids

The bundle's real value is that exchanges, queues, bindings, producers, and consumers are declared once in YAML and materialised as container services. Your application code never touches AMQPExchange / AMQPQueue directly — it injects a configured producer by id and hands it an envelope.

use Humus\Amqp\Producer;
use Humus\Amqp\JsonEnvelope;

final class OrderPlacedPublisher
{
    public function __construct(private Producer $producer) {}

    public function publish(string $orderId): void
    {
        $this->producer->publish(new JsonEnvelope(['order_id' => $orderId]), 'orders');
    }
}

Wire the concrete producer via a service alias in config/services.yaml (confirm the generated service id with bin/console debug:container --show-private | grep humus):

services:
    App\Amqp\OrderPlacedPublisher:
        arguments: ['@humus_amqp.producer.order_publisher']

2. Consumers are callback services, not subclasses

The bundle expects the callback key to reference a container service (typically !service or a class name resolved through the container). Keep handlers as plain invokable services so they are unit-testable without AMQP:

final class OrderCreatedHandler
{
    public function __invoke(Envelope $envelope, Consumer $consumer): void
    {
        // idempotent work here
        $consumer->acknowledge($envelope);
    }
}

The exact callback arity differs across HumusAmqp versions — check the Consumer::setCallback call site in the bundle before writing the signature.

3. One process, many consumers

For a small deployment, use the ConsumerManager (or the bundle's console command with multiple ids) to run several consumers in a single supervisor process instead of one process per queue. This is cheaper but couples failure domains — a fatal in one callback kills all consumers in that process.

4. Long-running worker shape

Day-to-day the consumer is a daemon. Standard shape:

  • Run under Supervisor/systemd with autorestart=true.
  • Send SIGTERM for graceful stop; the consumer loop should finish the current delivery, flush(), and exit.
  • Set prefetch (qos) low (1–10) on the consumer so a slow handler doesn't hoard messages.
  • Restart the worker periodically (memory creep from Doctrine entities, loggers, and closure captures is the normal failure mode).

5. Laravel translation

If you're porting the pattern into Laravel rather than using the bundle:

HumusAmqpBundle concept Laravel equivalent
humus_amqp.producers.* + injected Producer Queue::connection('rabbitmq')->push(...) or a small publisher service bound in a provider
consumers.*.callback service php artisan queue:work + a Job class handle()
humus:consume queue:work --queue=...
YAML topology declarations config/queue.php + a topology setup command, or rabbitmqadmin definitions file

The topology-as-config idea is worth copying; the runtime is not.

Gotchas and Tips

Hard blockers

  • ext-amqp is mandatory. It is a PECL C extension that wraps librabbitmq. If your target runtime (Heroku, some shared hosts, AWS Lambda) can't load it, this bundle is a dead end. php-amqplib-based packages (the Laravel ecosystem default) have no such constraint.
  • Symfony-only. The bundle registers compiler passes and a DI extension; there is no Laravel path. Do not try to squeeze it in via a custom ServiceProvider.
  • Adoption risk is real. Low star count and effectively no known dependents, so there is no community to catch a BC break for you. v2.3.0 is a maintenance-only release — Symfony 7 component constraints, no feature or API changes — which is a positive signal (the package is not abandoned) but tells you nothing about runtime stability. Pin an exact version in composer.json, commit composer.lock, and diff the source between upgrades.

Config quirks

  • The config tree is strict; unknown keys throw at cache-warm. After editing humus_amqp.yaml always run bin/console cache:clear, otherwise debug:container lies to you.
  • Config keys are not the same as the underlying HumusAmqp object constructor arguments. The bundle reshapes them. When something behaves oddly (e.g. a missing binding), dump the compiled container and check the argument order.
  • Service id collisions: if you have your own service named orders and also declare a producer with id orders, you'll get a confusing override. Prefix ids (humus.producer.orders) if you have a large container.
  • Upgrading to v2.3.0: the only declared change is the Symfony 7 constraint widening, but it moves the floor for the whole dependency graph. Run composer why-not symfony/framework-bundle 7 and composer update --dry-run genhoi/humus-amqp-bundle prolic/humus-amqp before committing; if prolic/humus-amqp (or any transitive package) still caps at Symfony 6, you'll get a resolution failure that looks like a bundle problem but isn't. Bump the bundle alone, not the framework, and keep the lockfile diff in the PR.

Runtime pitfalls

  • Topology is not magic. Exchanges/queues are declared when the connection is first used by a producer/consumer. If the RabbitMQ user lacks configure permission on the vhost you'll get a 403 ACCESS_REFUSED at the producer, not at boot. Test with a low-privilege user before deploying.
  • Ack/nack is your responsibility. The callback must ack (or the consumer will redeliver after channel close). Wrap handlers in try/catch; on failure either nack with requeue=false into a dead-letter exchange or explicitly reject. Configure the DLX via queue arguments (x-dead-letter-exchange) in config — the bundle passes arguments through.
  • Silent message loss on publish. Without publisher confirms configured, a broker hiccup drops messages. If the bundle version exposes confirms, enable them for anything financial or idempotency-critical.
  • Graceful shutdown needs a timeout. If the consumer blocks in consume() indefinitely, SIGTERM won't be noticed until the next poll. Set a non-zero timeout (and idle timeout where supported) so the loop wakes up.
  • Memory. Long-running consumers leak. unset() large payloads, avoid capturing the container in the callback, and schedule restarts.

Extension points

  • Override the producer/consumer class in config to inject your own implementation (e.g. a logging producer wrapping the default) rather than editing vendor code.
  • Decorate the generated producer service with a Symfony decorator for metrics/tracing.
  • The bundle's ConsumerManager / console command is the seam for custom scheduling: if you need cron-style consumers, write your own Command that resolves humus_amqp.consumer.<id> and calls consume() itself — do not fork the vendor command.

When to walk away

If the evaluation is "should we adopt this for a Laravel service?" the answer is no — use vladimir-yuldashev/laravel-queue-rabbitmq, or php-amqplib directly with a thin topology-definitions file. Revisit this bundle only if you are already inside a Symfony app where it is installed (v2.3.0 makes it viable on Symfony 6.4/7.x hosts), in which case the winning move is to read DependencyInjection/Configuration.php on day one and treat it as documentation.

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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console