snapshot of https://github.com/ThreeDotsLabs/watermill.git (master, 2026-09-15; blobs > 131072B omitted)
Some checks failed
master / ci (push) Failing after 0s
Some checks failed
master / ci (push) Failing after 0s
This commit is contained in:
199
components/cqrs/cqrs.go
Normal file
199
components/cqrs/cqrs.go
Normal file
@@ -0,0 +1,199 @@
|
||||
package cqrs
|
||||
|
||||
import (
|
||||
stdErrors "errors"
|
||||
|
||||
"github.com/ThreeDotsLabs/watermill"
|
||||
"github.com/ThreeDotsLabs/watermill/message"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Deprecated: use CommandProcessor and EventProcessor instead.
|
||||
type FacadeConfig struct {
|
||||
// GenerateCommandsTopic generates topic name based on the command name.
|
||||
// Command name is generated by CommandEventMarshaler's Name method.
|
||||
//
|
||||
// It allows you to use topic per command or one topic for every command.
|
||||
GenerateCommandsTopic func(commandName string) string
|
||||
|
||||
// CommandHandlers return command handlers which should be executed.
|
||||
CommandHandlers func(commandBus *CommandBus, eventBus *EventBus) []CommandHandler
|
||||
|
||||
// CommandsPublisher is Publisher used to publish commands.
|
||||
CommandsPublisher message.Publisher
|
||||
|
||||
// CommandsSubscriberConstructor is constructor for subscribers which will subscribe for messages.
|
||||
// It will be called for every command handler.
|
||||
// It allows you to create separated customized Subscriber for every command handler.
|
||||
CommandsSubscriberConstructor CommandsSubscriberConstructor
|
||||
|
||||
// GenerateEventsTopic generates topic name based on the event name.
|
||||
// Event name is generated by CommandEventMarshaler's Name method.
|
||||
//
|
||||
// It allows you to use topic per command or one topic for every command.
|
||||
GenerateEventsTopic func(eventName string) string
|
||||
|
||||
// EventHandlers return event handlers which should be executed.
|
||||
EventHandlers func(commandBus *CommandBus, eventBus *EventBus) []EventHandler
|
||||
|
||||
// EventsPublisher is Publisher used to publish commands.
|
||||
EventsPublisher message.Publisher
|
||||
|
||||
// EventsSubscriberConstructor is constructor for subscribers which will subscribe for messages.
|
||||
// It will be called for every event handler.
|
||||
// It allows you to create separated customized Subscriber for every event handler.
|
||||
EventsSubscriberConstructor EventsSubscriberConstructor
|
||||
|
||||
// Router is a Watermill router, which will be used to handle events and commands.
|
||||
// Router handlers will be automatically generated by AddHandlersToRouter of Command and Event handlers.
|
||||
Router *message.Router
|
||||
|
||||
CommandEventMarshaler CommandEventMarshaler
|
||||
|
||||
Logger watermill.LoggerAdapter
|
||||
}
|
||||
|
||||
func (c FacadeConfig) Validate() error {
|
||||
var err error
|
||||
|
||||
if c.CommandsEnabled() {
|
||||
if c.GenerateCommandsTopic == nil {
|
||||
err = stdErrors.Join(err, errors.New("GenerateCommandsTopic is nil"))
|
||||
}
|
||||
if c.CommandsSubscriberConstructor == nil {
|
||||
err = stdErrors.Join(err, errors.New("CommandsSubscriberConstructor is nil"))
|
||||
}
|
||||
if c.CommandsPublisher == nil {
|
||||
err = stdErrors.Join(err, errors.New("CommandsPublisher is nil"))
|
||||
}
|
||||
}
|
||||
if c.EventsEnabled() {
|
||||
if c.GenerateEventsTopic == nil {
|
||||
err = stdErrors.Join(err, errors.New("GenerateEventsTopic is nil"))
|
||||
}
|
||||
if c.EventsSubscriberConstructor == nil {
|
||||
err = stdErrors.Join(err, errors.New("EventsSubscriberConstructor is nil"))
|
||||
}
|
||||
if c.EventsPublisher == nil {
|
||||
err = stdErrors.Join(err, errors.New("EventsPublisher is nil"))
|
||||
}
|
||||
}
|
||||
|
||||
if c.Router == nil {
|
||||
err = stdErrors.Join(err, errors.New("Router is nil"))
|
||||
}
|
||||
if c.Logger == nil {
|
||||
err = stdErrors.Join(err, errors.New("Logger is nil"))
|
||||
}
|
||||
if c.CommandEventMarshaler == nil {
|
||||
err = stdErrors.Join(err, errors.New("CommandEventMarshaler is nil"))
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c FacadeConfig) EventsEnabled() bool {
|
||||
return c.GenerateEventsTopic != nil || c.EventsPublisher != nil || c.EventsSubscriberConstructor != nil
|
||||
}
|
||||
|
||||
func (c FacadeConfig) CommandsEnabled() bool {
|
||||
return c.GenerateCommandsTopic != nil || c.CommandsPublisher != nil || c.CommandsSubscriberConstructor != nil
|
||||
}
|
||||
|
||||
// Deprecated: use CommandHandler and EventHandler instead.
|
||||
//
|
||||
// Facade is a facade for creating the Command and Event buses and processors.
|
||||
// It was created to avoid boilerplate, when using CQRS in the standard way.
|
||||
// You can also create buses and processors manually, drawing inspiration from how it's done in NewFacade.
|
||||
type Facade struct {
|
||||
commandsTopic func(commandName string) string
|
||||
commandBus *CommandBus
|
||||
|
||||
eventsTopic func(eventName string) string
|
||||
eventBus *EventBus
|
||||
|
||||
commandEventMarshaler CommandEventMarshaler
|
||||
}
|
||||
|
||||
func (f Facade) CommandBus() *CommandBus {
|
||||
return f.commandBus
|
||||
}
|
||||
|
||||
func (f Facade) EventBus() *EventBus {
|
||||
return f.eventBus
|
||||
}
|
||||
|
||||
func (f Facade) CommandEventMarshaler() CommandEventMarshaler {
|
||||
return f.commandEventMarshaler
|
||||
}
|
||||
|
||||
// Deprecated: use CommandHandler and EventHandler instead.
|
||||
func NewFacade(config FacadeConfig) (*Facade, error) {
|
||||
if err := config.Validate(); err != nil {
|
||||
return nil, errors.Wrap(err, "invalid config")
|
||||
}
|
||||
|
||||
c := &Facade{
|
||||
commandsTopic: config.GenerateCommandsTopic,
|
||||
eventsTopic: config.GenerateEventsTopic,
|
||||
commandEventMarshaler: config.CommandEventMarshaler,
|
||||
}
|
||||
|
||||
if config.CommandsEnabled() {
|
||||
var err error
|
||||
c.commandBus, err = NewCommandBus(
|
||||
config.CommandsPublisher,
|
||||
config.GenerateCommandsTopic,
|
||||
config.CommandEventMarshaler,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "cannot create command bus")
|
||||
}
|
||||
} else {
|
||||
config.Logger.Info("Empty GenerateCommandsTopic, command bus will be not created", nil)
|
||||
}
|
||||
if config.EventsEnabled() {
|
||||
var err error
|
||||
c.eventBus, err = NewEventBus(config.EventsPublisher, config.GenerateEventsTopic, config.CommandEventMarshaler)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "cannot create event bus")
|
||||
}
|
||||
} else {
|
||||
config.Logger.Info("Empty GenerateEventsTopic, event bus will be not created", nil)
|
||||
}
|
||||
|
||||
if config.CommandHandlers != nil {
|
||||
commandProcessor, err := NewCommandProcessor(
|
||||
config.CommandHandlers(c.commandBus, c.eventBus),
|
||||
config.GenerateCommandsTopic,
|
||||
config.CommandsSubscriberConstructor,
|
||||
config.CommandEventMarshaler,
|
||||
config.Logger,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "cannot create command processor")
|
||||
}
|
||||
|
||||
if err := commandProcessor.AddHandlersToRouter(config.Router); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if config.EventHandlers != nil {
|
||||
eventProcessor, err := NewEventProcessor(
|
||||
config.EventHandlers(c.commandBus, c.eventBus),
|
||||
config.GenerateEventsTopic,
|
||||
config.EventsSubscriberConstructor,
|
||||
config.CommandEventMarshaler,
|
||||
config.Logger,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "cannot create event processor")
|
||||
}
|
||||
|
||||
if err := eventProcessor.AddHandlersToRouter(config.Router); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
Reference in New Issue
Block a user