Skip to content

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:

go
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:

go
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:

go
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:

go
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:

go
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.