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.
-
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.
Spring Outbox provides a simple way to implement the transactional outbox pattern in your Spring applications.
-
Add dependency
<dependency> <groupId>io.github.raedbh</groupId> <artifactId>spring-outbox-jpa</artifactId> <version>0.7.0</version> </dependency>
-
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); } }
-
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; } }
-
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.
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. |
The project requires JDK 17 or higher.
To compile, test, and build the project, run:
./mvnw installTo include Testcontainers tests (require Docker), run:
./mvnw install -Dspring.profiles.active=testcontainersSpring Outbox follows the Spring Framework Code Style. You find here the project formatters for Eclipse and Intellij.
Spring Outbox is licensed under Apache 2.0 license.