Identifier
In comby, the Identifier
is used to augment the framework's core interfaces — such as Aggregate
, CommandHandler
, QueryHandler
, and Readmodel
— with additional metadata: a Domain and a Name. This augmentation provides a lightweight yet powerful way to associate these components with their respective domains and to distinguish them within the system.
The Identifier
interface in comby is defined as follows:
type Identifier interface {
// GetIdentifier returns the unique identifier as a string, typically
// in the format "Domain.Name".
GetIdentifier() string
// GetDomain returns the domain part of the identifier.
GetDomain() string
// GetName returns the name part of the identifier.
GetName() string
}
By adhering to this interface, the Identifier
ensures that every component it augments is identifiable within the domain-driven design of comby, making it easier to manage and coordinate the application's components in an event-sourced, CQRS-based architecture.
Base Idenfitier
The BaseIdentifier
is a straightforward yet pivotal implementation of the Identifier
interface. While its structure is straightforward, its impact is significant. By providing this information, the system can ensure precise association of events with their corresponding components. This is particularly critical in Event Sourcing, where for example events need to be accurately routed based on their origin and context.
The BaseIdentifier
provides a default implementation of the Identifier
interface and fully satisfies its method requirements. Its structure is defined as follows:
type BaseIdentifier struct {
Domain string `json:"domain,omitempty"` // Domain represents the logical grouping of the identifier.
Name string `json:"name,omitempty"` // Name represents the specific entity within the domain.
}
When a BaseIdentifier
is created using the NewBaseIdentifier
function, its Domain and Name fields are set to default values. Specifically:
- Domain is initialized to "Default"
- Name is initialized as an empty string ("")
Here’s the default constructor:
func NewBaseIdentifier() *BaseIdentifier {
bi := &BaseIdentifier{}
bi.Domain = DEFAULT_DOMAIN // Predefined default domain value.
bi.Name = "" // Empty by default.
return bi
}
The BaseIdentifier
is embedded in comby's base components to provide consistent Domain and Name metadata. These include:
BaseAggregate
BaseCommandHandler
BaseQueryHandler
BaseReadmodel
This embedding ensures that all base components in the framework are equipped with Domain and Name metadata, facilitating streamlined event routing and processing.
Usage
From a developer's perspective, the BaseIdentifier
is simple to use and can be accessed and customized directly within comby components. For example:
Defining a New Aggregate
BaseIdentifier
already embedded in BaseAggregate
:
func NewAggregate() *MyAggregate {
agg := &MyAggregate{}
agg.BaseAggregate = comby.NewBaseAggregate()
// ...
agg.Domain = "MyDomain"
agg.Name = "MyAggregate"
// ...
return agg
}
Defining a New Query Handler
BaseIdentifier
already embedded in BaseQueryHandler
:
func NewQueryHandler(
Readmodel *readmodel.AnyReadmodel,
) *myQueryHandler {
qs := &myQueryHandler{}
qs.BaseQueryHandler = comby.NewBaseQueryHandler()
// ...
qs.Domain = "MyDomain"
qs.Name = "MyQueryHandler"
// ...
return qs
}
Embedding BaseIdentifier
ensures all components align with the same Domain and Name convention.