Event Subscribers
Event Subscribers react to typed events.
Subscribers are useful for fan-out, secondary reactions, and integration points. They should stay explicit and observable.
Generate a Subscriber
Generate a subscriber from the event name:
forj make:subscriber billing:invoice-paidUse --bus when the subscriber should attach to a named event bus:
forj make:subscriber billing:invoice-paid --bus auditThe named bus must be configured, for example with EVENTS_AUDIT_DRIVER.
Dispatch Durable Follow-up Work
A subscriber can hand retryable work to a generated job:
_, err := bus.WithContext(ctx).Subscribe(func(ctx context.Context, event UserRegisteredEvent) error {
return welcomeEmails.Queue(ctx, event.UserID)
})The event announces the fact. If work must be durable or retried, the subscriber can dispatch a job.
Registration Timing
Register subscribers through generated or documented App registration surfaces before the event runtime starts.
Subscriber registration should be visible in App construction, not hidden in package init functions.
The generated-code tab shows the maintained registration path. That App-owned injector is rendered once and preserved across re-renders, so manual subscriber wiring can live beside generated entries.
The event type itself does not belong in the provider graph. The subscriber object or registrar does, because it may need services, repositories, queues, or publishers injected before it subscribes to the bus during App startup.
Error Handling
Event bus behavior depends on the driver. Do not assume subscriber errors are durable retry signals.
Handle important subscriber failures deliberately:
- return errors when the driver observes them
- log or record metrics where appropriate
- dispatch jobs for retryable work
- make critical reactions explicit instead of best-effort
Test the Reaction
Test the subscriber as an ordinary Go type: construct it with fakes for its required services, call Handle with a typed event, and assert the one intended reaction. Include a dependency-error case and assert the returned error instead of relying on logs.
Then add one App-level test that publishes through the configured in-process bus and proves the generated registration invokes the subscriber. That second test catches a missing provider or Subscribe call that a direct handler test cannot see.
For a distributed bus, the release smoke test must cross processes. Publish a non-production event through one deployed process and confirm the intended subscriber process records the stable topic and outcome. A successful publisher call alone does not prove subscription, delivery, or remote credentials.
Good Uses
Subscribers are a good fit for:
- publishing follow-up events
- dispatching background jobs
- recording audit facts
- updating derived projections
- notifying non-critical integrations
Use queues for durable, retryable, worker-managed work.
Next Steps
- Events explains event publishing.
- Jobs explains durable background work.
- Retries and Idempotency explains safe retry design.
make:subscriberReference lists bus selection, removal, and generated registration.