This is a Go language package for publishing/subscribing domain events. This is useful to decouple subdomains within applications. Here is a sketch for using this package in real world applications.
package main
import (
"context"
"fmt"
"time"
"github.com/itchyny/event-go"
)
// Domain entity.
type User struct {
ID int64
Created time.Time
UserValue
}
// Domain value object.
type UserValue struct {
Name string
Email string
}
// Domain event types.
const (
EventTypeUserCreated event.Type = iota + 1
EventTypeUserRetired
)
// Domain events.
type UserCreated struct{ User *User }
type UserRetired struct{ User *User }
// Define the type of the events.
func (ev *UserCreated) Type() event.Type { return EventTypeUserCreated }
func (ev *UserRetired) Type() event.Type { return EventTypeUserRetired }
type App struct{ event.Mapping }
func NewApp() *App {
app := &App{event.NewMapping()}
// Register mapping of event types and subscribers.
app.
On(
EventTypeUserCreated,
event.Func(func(ctx context.Context, ev event.Event) error {
return app.SendNotification(ctx, NotifyUserCreated, ev.(*UserCreated).User)
}),
).
On(
EventTypeUserRetired,
event.Func(func(ctx context.Context, ev event.Event) error {
return app.SendNotification(ctx, NotifyUserRetired, ev.(*UserRetired).User)
}),
)
return app
}
func (app *App) CreateUser(ctx context.Context, user *UserValue) (*User, error) {
fmt.Printf("CreateUser: %#v\n", user)
created := &User{1, time.Now(), *user}
// Publish a domain event, instead of calling SendNotification directly.
_ = app.Publish(ctx, &UserCreated{User: created})
return created, nil
}
func (app *App) RetireUser(ctx context.Context, user *User) error {
fmt.Printf("RetireUser: %#v\n", user)
// Publish a domain event, instead of calling SendNotification directly.
_ = app.Publish(ctx, &UserRetired{User: user})
return nil
}
type NotificationType int
const (
NotifyUserCreated NotificationType = iota + 1
NotifyUserRetired
)
func (typ NotificationType) String() string {
switch typ {
case NotifyUserCreated:
return "created"
case NotifyUserRetired:
return "retired"
default:
panic(typ)
}
}
func (app *App) SendNotification(_ context.Context, typ NotificationType, user *User) error {
fmt.Printf("SendNotification(%s): %#v\n", typ, user)
// Send email or something.
return nil
}
func main() {
ctx := context.Background()
app := NewApp()
user, _ := app.CreateUser(ctx, &UserValue{"Test User", "[email protected]"})
_ = app.RetireUser(ctx, user)
}
Report bug at Issues・itchyny/event-go - GitHub.
itchyny (https://github.com/itchyny)
This software is released under the MIT License, see LICENSE.