Structus API Reference
Complete API documentation for the Structus library.
Core Aggregates
Base interfaces and classes for building domain models
AggregateRoot<ID>Base interface for aggregate root entities. All domain model aggregates must implement this interface.
Parameters
IDSerializablerequiredThe type of the aggregate's identifier
Returns
Type: Entity with event sourcing capabilities
Provides methods for managing domain events and state changes
Example
data class OrderAggregate(
override val id: OrderId,
val items: List<OrderItem> = emptyList(),
val status: OrderStatus = OrderStatus.PENDING
) : AggregateRoot<OrderId> {
override fun getUncommittedEvents(): List<DomainEvent> {
return emptyList()
}
}Entity<ID>Base interface for entities within an aggregate. Entities have identity and lifecycle within aggregates.
Parameters
IDSerializablerequiredThe type of the entity's identifier
Returns
Type: Entity with value object support
Supports composition with value objects for rich domain models
ValueObjectAbstract base class for value objects. Value objects have no identity and are immutable.
Returns
Type: Immutable domain concept
Used for modeling concepts like Money, Email, or ProductCode
Example
data class Money(
val amount: BigDecimal,
val currency: Currency
) : ValueObject() {
init {
require(amount >= BigDecimal.ZERO) { "Amount must be non-negative" }
}
}Repository Pattern
Interfaces for persisting and retrieving aggregates
Repository<T, ID>Base repository interface for storing and retrieving aggregates of type T
Parameters
TAggregateRoot<ID>requiredThe aggregate root type
IDSerializablerequiredThe aggregate's identifier type
Returns
Type: Query and persistence operations
Provides find, save, and delete operations
Example
interface OrderRepository : Repository<OrderAggregate, OrderId> {
suspend fun findByCustomerId(customerId: CustomerId): List<OrderAggregate>
suspend fun findRecentOrders(limit: Int): List<OrderAggregate>
}Command Handling
Interfaces for handling commands and business operations
CommandHandler<T, R>Handles a command of type T and returns a result of type R
Parameters
TCommandrequiredThe command to handle
RAnyrequiredThe return type of the command handler
Returns
Type: Result<R>
Either a successful result or a domain error
Example
class CreateOrderCommandHandler(
private val orderRepository: OrderRepository
) : CommandHandler<CreateOrderCommand, OrderId> {
override suspend fun handle(command: CreateOrderCommand): OrderId {
val order = OrderAggregate.create(
customerId = command.customerId,
items = command.items
)
orderRepository.save(order)
return order.id
}
}Best Practices
- Aggregate Design: Keep aggregates small and focused on a single responsibility
- Event Sourcing: Use domain events to capture state changes
- Repository Contract: Define repositories per aggregate, not per entity
- Command Validation: Validate commands at the handler level
- Error Handling: Use result types or exceptions for domain errors