Aller au contenu principal
Version: Suivant

Structus API Reference

Complete API documentation for the Structus library.

Core Aggregates

Base interfaces and classes for building domain models

INTERFACEAggregateRoot<ID>

Base interface for aggregate root entities. All domain model aggregates must implement this interface.

Parameters

IDSerializablerequired

The 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()
}
}
INTERFACEEntity<ID>

Base interface for entities within an aggregate. Entities have identity and lifecycle within aggregates.

Parameters

IDSerializablerequired

The type of the entity's identifier

Returns

Type: Entity with value object support

Supports composition with value objects for rich domain models

CLASSValueObject

Abstract 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

INTERFACERepository<T, ID>

Base repository interface for storing and retrieving aggregates of type T

Parameters

TAggregateRoot<ID>required

The aggregate root type

IDSerializablerequired

The 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

INTERFACECommandHandler<T, R>

Handles a command of type T and returns a result of type R

Parameters

TCommandrequired

The command to handle

RAnyrequired

The 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

See Also