60 lines
1.8 KiB
Go
60 lines
1.8 KiB
Go
package cqrs
|
|
|
|
import (
|
|
"context"
|
|
)
|
|
|
|
// CommandHandler receives a command defined by NewCommand and handles it with the Handle method.
|
|
// If using DDD, CommandHandler may modify and persist the aggregate.
|
|
//
|
|
// In contrast to EventHandler, every Command must have only one CommandHandler.
|
|
//
|
|
// One instance of CommandHandler is used during handling messages.
|
|
// When multiple commands are delivered at the same time, Handle method can be executed multiple times at the same time.
|
|
// Because of that, Handle method needs to be thread safe!
|
|
type CommandHandler interface {
|
|
// HandlerName is the name used in message.Router while creating handler.
|
|
//
|
|
// It will be also passed to CommandsSubscriberConstructor.
|
|
// May be useful, for example, to create a consumer group per each handler.
|
|
//
|
|
// WARNING: If HandlerName was changed and is used for generating consumer groups,
|
|
// it may result with **reconsuming all messages**!
|
|
HandlerName() string
|
|
|
|
NewCommand() any
|
|
|
|
Handle(ctx context.Context, cmd any) error
|
|
}
|
|
|
|
type genericCommandHandler[Command any] struct {
|
|
handleFunc func(ctx context.Context, cmd *Command) error
|
|
handlerName string
|
|
}
|
|
|
|
// NewCommandHandler creates a new CommandHandler implementation based on provided function
|
|
// and command type inferred from function argument.
|
|
func NewCommandHandler[Command any](
|
|
handlerName string,
|
|
handleFunc func(ctx context.Context, cmd *Command) error,
|
|
) CommandHandler {
|
|
return &genericCommandHandler[Command]{
|
|
handleFunc: handleFunc,
|
|
handlerName: handlerName,
|
|
}
|
|
}
|
|
|
|
func (c genericCommandHandler[Command]) HandlerName() string {
|
|
return c.handlerName
|
|
}
|
|
|
|
func (c genericCommandHandler[Command]) NewCommand() any {
|
|
tVar := new(Command)
|
|
return tVar
|
|
}
|
|
|
|
func (c genericCommandHandler[Command]) Handle(ctx context.Context, cmd any) error {
|
|
command := cmd.(*Command)
|
|
return c.handleFunc(ctx, command)
|
|
}
|