Como publicar un evento de dominio
Tres pasos: definir el payload, agregarlo al agregado, guardar el agregado.
No hay paso explicito de "publicar" en el caso de uso — el adaptador de persistencia drena los eventos del agregado al outbox dentro de la misma transaccion que el save, y un dispatcher en background los publica al transport.
1. Definir el payload
Un record inmutable bajo events/{dominio}/:
package com.example.events.task;
import com.example.commons.messaging.event.DomainEvent;
import com.example.task.domain.Task;
public record TaskCreatedEvent(String id) {
public static DomainEvent<TaskCreatedEvent> of(Task task) {
return DomainEvent.create(
task::getId,
task.getClass().getCanonicalName(),
new TaskCreatedEvent(task.getId())
);
}
}
DomainEvent.create(…) envuelve el payload con metadata. Para los campos disponibles y eventos "inceptive" (creacion sin id aun) ver Referencia: DomainEvent.
2. Agregarlo al agregado
El agregado expone Set<DomainEvent<?>> domainEvents (transient). Se llena en el constructor para eventos de creacion, o desde metodos de negocio para transiciones:
@Entity
@Table(name = "task")
public class Task extends AlphaIdEntity {
@Transient
private Set<DomainEvent<?>> domainEvents = new LinkedHashSet<>();
public Task() {
domainEvents.add(TaskCreatedEvent.of(this));
}
public void complete() {
// ... mutar estado
domainEvents.add(TaskCompletedEvent.of(this));
}
}
3. Guardar el agregado
@Service
@RequiredArgsConstructor
class TaskService implements CreateTaskUseCase {
private final TaskPersistencePort persistencePort;
@Override
public String create(CreateTaskCommand command) {
Task entity = new Task();
persistencePort.save(entity);
return entity.getId();
}
}
Listo. El PersistenceAdapter registra los eventos en el outbox dentro de la misma TX que el INSERT del agregado.
Verificar que salio
Despues de llamar al caso de uso, curl http://localhost:8080/actuator/message-boxes muestra el conteo de events.outbox. Para detalle del endpoint ver Inspeccionar las bandejas de mensajeria.
Ver tambien
-
Procesar un evento de dominio — del otro lado: como reaccionar al evento.
-
Referencia: Mensajeria —
DomainEvent, propiedadesapp.events.*, estados. -
Decisiones de mensajeria — por que outbox y no publicacion directa.