Skip to content

raedbh/spring-outbox

Repository files navigation

Spring Outbox

Spring Outbox is an implementation of the transactional outbox pattern that helps Spring developers implement an efficient event-driven architecture for microservices and monolithic applications.

Implementation Key Considerations

  • When a domain event occurs, it generates one or more messages.

  • Each outbox entry represents either an event or a command.

  • An operation, part of an event, represents the action performed on the root entity (e.g., create, update, award) and helps consumers determine if deserialization is needed.

  • Decouple the outbox message producer and consumer to enable scalability and independent evolution.

  • Keep the Debezium connector simple by focusing on reading outbox entries and producing messages.

Getting Started

Spring Outbox provides a simple way to implement the transactional outbox pattern in your Spring applications.

Quick Start

  1. Add dependency

    <dependency>
        <groupId>io.github.raedbh</groupId>
        <artifactId>spring-outbox-jpa</artifactId>
        <version>0.7.0</version>
    </dependency>
  2. Enable Spring Outbox

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
    
    import io.github.raedbh.spring.outbox.jpa.OutboxJpaRepositoryFactoryBean;
    
    @SpringBootApplication
    @EnableJpaRepositories(repositoryFactoryBeanClass = OutboxJpaRepositoryFactoryBean.class)
    public class Application {
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    }
  3. Create your aggregate root

    import java.util.UUID;
    
    import jakarta.persistence.Entity;
    import jakarta.persistence.Id;
    
    import io.github.raedbh.spring.outbox.core.RootEntity;
    
    @Entity
    public class Order extends RootEntity {
    
        private @Id UUID id;
        // other fields...
    
        public Order markPaid() {
            // business logic
            assignEvent(new OrderPlaced(this));
            return this;
        }
    }
  4. Define your domain event

    import io.github.raedbh.spring.outbox.core.EventOutboxed;
    
    public class OrderPlaced extends EventOutboxed<Order> {
    
        public OrderPlaced(Order source) {
            super(source);
        }
    
        @Override
        public String getOperation() {
            return "payment";
        }
    }

That’s almost what you need to have outbox entries stored into the database. The remaining part involves using Debezium to capture changes and Spring Outbox messaging modules for downstream components to consume the messages.

For a complete implementation example, see the S2P application sample.

Contribution

There are several ways to contribute to Spring Outbox:

  • Open Issues: If you find bugs, or you have ideas for improvement, feel free to open an issue.

  • Start Discussions: Join ongoing conversations or start a new one in the Discussions tab to share feedback or provide suggestions.

  • Submit Pull Requests: If you have a fix or improvement, fork the repository and submit a pull request.

Note
If you’d like to work on an issue, please comment on it first and briefly describe the approach you plan to take. This ensures alignment with the project’s direction and avoids duplicate efforts.

Building

The project requires JDK 17 or higher.

To compile, test, and build the project, run:

./mvnw install

To include Testcontainers tests (require Docker), run:

./mvnw install -Dspring.profiles.active=testcontainers

Code Style

Spring Outbox follows the Spring Framework Code Style. You find here the project formatters for Eclipse and Intellij.

License

Spring Outbox is licensed under Apache 2.0 license.

Releases

No releases published

Packages

No packages published