1

I’m building a Java microservice using Spring Boot 3.5.7, Kafka, and the Outbox Pattern.

In my domain layer, I raise a domain event:

package com.turkcell.reservation_service.domain.event;

import com.turkcell.reservation_service.domain.model.BookId;
import com.turkcell.reservation_service.domain.model.ReservationId;
import com.turkcell.reservation_service.domain.model.ReservationStatus;

import java.time.OffsetDateTime;

public record ReservationCreatedEvent(
        ReservationId id,
        OffsetDateTime reservationDate,
        ReservationStatus reservationStatus,
        BookId bookId) {
}

Then, in my command handler, I convert this domain event to an integration event before saving it to the Outbox table:

@Override
@Transactional
public ReservationResponse handle(CreateReservationCommand command) throws JsonProcessingException {
    
    Reservation reservation = reservationMapper.toDomain(command);
    reservationRepository.save(reservation);

    //Domain Event to Integration Event
    ReservationCreatedEvent event = new ReservationCreatedEvent(
            new ReservationId(reservation.id().value()),
            reservation.reservationDate(),
            reservation.status(),
            new BookId(reservation.bookId().value()));
    
    ReservationCreatedIntegrationEvent integrationEvent = integrationEventMapper.toIntegrationEvent(event);
    
    Outbox outbox = outboxMapper.toOutbox(integrationEvent);
    outbox.setPayloadJson(objectMapper.writeValueAsString(integrationEvent));
    outboxRepository.save(outbox);  //save event to outbox as json

    return reservationMapper.toResponse(reservation);
}

My question is:
In a DDD-based microservice using the Outbox Pattern, is it recommended to create a separate Integration Event object, or can the Domain Event itself be serialized and saved to the Outbox table?

I’m looking for a fact-based explanation — ideally with reasoning or references from DDD or Clean Architecture literature (e.g., Vaughn Vernon’s Implementing Domain-Driven Design or Chris Richardson’s Microservices Patterns).

I want to understand the architectural implications of both approaches (in terms of bounded contexts, coupling, and event evolution), not just personal preference

1 Answer 1

2

Is it really necessary to create a separate ReservationCreatedIntegrationEvent object, or can I directly serialize and save the domain event itself into the Outbox table?

As far as I can tell, the authoritative answers are:

  • Is it necessary? No.
  • Is it a good idea? Often.

But their nature, an "integration event" like this one is an internal representation of some message schema that is shared by you and somebody else. Making changes (in particular, making backwards incompatible changes) to a shared message schema tends to be expensive (because of the coordination required). In effect, we end up with this constraint that the "payload json" -- the bytes that we are putting into the outbox -- shouldn't change arbitrarily.

If you decide that you don't need a dedicated integration event, now your domain model's internal representation of that information inherits the same constraints.

In other words, you've compromised your ability to improve this part of the design.

Now, in the abstract, it's not terribly difficult to come along later and say "whoops, our new vision for the domain model's representation of the event no longer matches the integration schema, so we're going to introduce the extra ceremony of an explicit event to separate the two". The You-Arent-Gonna-Need-It is based on this idea: we choose the expedient design now because it's cheap to change it later.

But a truth of the world: bad design decisions tend to become load bearing, which means that maybe this decision isn't going to be cheap to change later. And when decisions aren't going to be cheap to change later, we really want to invest some design capital to make a good decision early.

You end up with different sets of tradeoffs in a stable, familiar domain than one you are exploring for the first time.

In short: it depends?

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.