Skip to main content

Event Bus

VEF boots an in-memory event bus and exposes it through the public event package.

What The Module Provides Automatically

The event module registers one in-memory bus that is exposed as:

Interface
event.Bus
event.Publisher
event.Subscriber

The bus is started and stopped through the FX lifecycle automatically.

Core Event Interfaces

event.Event

Custom events should implement:

MethodMeaning
ID()unique event instance ID
Type()event type string
Source()source that produced the event
Time()occurrence time
Meta()metadata map

Publish and subscribe interfaces

InterfaceMethod
event.PublisherPublish(event)
event.SubscriberSubscribe(eventType, handler)
event.Buscombines publisher, subscriber, Start(), and Shutdown(ctx)

Middleware interfaces

Interface or typePurpose
event.Middlewareintercept event delivery
event.MiddlewareFuncnext function in the middleware chain

event.BaseEvent

Most custom events embed event.BaseEvent:

type UserCreatedEvent struct {
event.BaseEvent

UserID string `json:"userId"`
}

Create the base part with:

&UserCreatedEvent{
BaseEvent: event.NewBaseEvent(
"user.created",
event.WithSource("user-service"),
event.WithMeta("scope", "admin"),
),
UserID: "user-1001",
}

Base event helpers:

HelperMeaning
event.NewBaseEvent(type, opts...)creates a new base event
event.WithSource(source)sets the source field
event.WithMeta(key, value)adds metadata

Publish and Subscribe Example

package userevents

import (
"context"

"github.com/coldsmirk/vef-framework-go/event"
)

func PublishUserCreated(publisher event.Publisher, userID string) {
publisher.Publish(&UserCreatedEvent{
BaseEvent: event.NewBaseEvent("user.created"),
UserID: userID,
})
}

func RegisterUserCreatedHandler(subscriber event.Subscriber) event.UnsubscribeFunc {
return subscriber.Subscribe("user.created", func(ctx context.Context, evt event.Event) {
_ = evt
})
}

Event Middleware

The bus supports event middleware through the FX group:

vef:event:middlewares

This is the place for cross-cutting concerns such as:

  • event logging
  • tracing
  • filtering
  • event mutation before delivery

Built-In Framework Event Types

The framework itself currently publishes these core event types:

Event typeSource
vef.api.request.auditAPI audit event
vef.security.loginlogin flow event
vef.storage.file.promotedstorage promoter event
vef.storage.file.deletedstorage promoter event
vef.security.role_permissions.changedrole-permission cache invalidation event

If the approval module is enabled, it also publishes additional approval-domain events on top of these framework-level events.

Typical Wiring Pattern

In larger apps, subscribers are often registered through an integration module instead of inside a resource:

var Module = vef.Module(
"app:event",
vef.Invoke(registerEventSubscribers),
)

That registerEventSubscribers function can subscribe to framework events and register lifecycle cleanup if needed.

When To Use It

The built-in event bus is a good fit when:

  • producer and consumer live in the same application
  • asynchronous decoupling is enough
  • you do not need an external broker yet

If you later need cross-process messaging, you can still keep the internal bus as the application-level abstraction.

Next Step

Read Cache if you want to connect event publishing with invalidation or async refresh flows.