event-sourcing-examples
Example code for my building and deploying microservices with event sourcing, CQRS and Docker presentation
Top Related Projects
Framework for Evolutionary Message-Driven Microservices on the JVM
EventStoreDB, the event-native database. Designed for Event Sourcing, Event-Driven, and Microservices architectures
Spring Boot helps you to create Spring-powered, production-grade applications and services with absolute minimum fuss.
Quick Overview
The cer/event-sourcing-examples repository is a collection of sample applications demonstrating event sourcing patterns in various programming languages and frameworks. It provides practical examples of implementing event sourcing architecture, helping developers understand and apply these concepts in real-world scenarios.
Pros
- Offers examples in multiple languages and frameworks, making it accessible to a wide range of developers
- Provides practical, real-world implementations of event sourcing concepts
- Includes detailed documentation and explanations for each example
- Regularly updated with new examples and improvements
Cons
- Some examples may be outdated or not follow the latest best practices
- The repository lacks a unified structure across all examples, which may confuse some users
- Not all examples are equally well-documented or maintained
- Some more complex scenarios or edge cases might not be covered
Code Examples
Here are a few code examples from the repository:
- Creating an event in Java (from the Java Spring Boot example):
@Value
public class OrderCreatedEvent implements Event {
String orderId;
String customerId;
BigDecimal orderTotal;
@Override
public String getAggregateId() {
return orderId;
}
}
- Handling an event in C# (from the .NET Core example):
public void Apply(OrderCreatedEvent @event)
{
Id = @event.OrderId;
CustomerId = @event.CustomerId;
Total = @event.OrderTotal;
Status = OrderStatus.Created;
}
- Dispatching an event in JavaScript (from the Node.js example):
const event = new OrderCreatedEvent({
orderId: uuid(),
customerId: customerId,
orderTotal: orderTotal
});
await eventStore.saveEvent(event);
await eventBus.publish(event);
Getting Started
To get started with the examples:
-
Clone the repository:
git clone https://github.com/cer/event-sourcing-examples.git
-
Navigate to the desired example directory:
cd event-sourcing-examples/<language-or-framework>
-
Follow the README instructions in the specific example directory for setup and running the application.
Note that each example may have different requirements and setup instructions, so be sure to read the documentation for the specific example you're interested in.
Competitor Comparisons
Framework for Evolutionary Message-Driven Microservices on the JVM
Pros of AxonFramework
- More comprehensive and mature framework for event sourcing and CQRS
- Provides built-in support for distributed systems and microservices
- Offers extensive documentation and a larger community for support
Cons of AxonFramework
- Steeper learning curve due to its complexity and extensive features
- May be overkill for smaller projects or simpler event sourcing implementations
- Requires more configuration and setup compared to simpler alternatives
Code Comparison
AxonFramework:
@Aggregate
public class Account {
@AggregateIdentifier
private String accountId;
private BigDecimal balance;
@CommandHandler
public Account(CreateAccountCommand cmd) {
apply(new AccountCreatedEvent(cmd.getAccountId(), cmd.getInitialBalance()));
}
}
event-sourcing-examples:
public class Account extends AggregateRoot {
private String id;
private BigDecimal balance;
public Account(String id, BigDecimal initialBalance) {
applyChange(new AccountCreatedEvent(id, initialBalance));
}
}
AxonFramework provides more annotations and built-in functionality, while event-sourcing-examples uses a simpler approach with less framework-specific code. AxonFramework's implementation is more declarative, whereas event-sourcing-examples is more explicit in its event application.
EventStoreDB, the event-native database. Designed for Event Sourcing, Event-Driven, and Microservices architectures
Pros of EventStore
- Production-ready, scalable event store database
- Supports multiple programming languages and platforms
- Provides built-in projections and subscriptions
Cons of EventStore
- Steeper learning curve for beginners
- Requires more setup and infrastructure management
- Less flexibility for custom implementations
Code Comparison
EventStore:
var connection = EventStoreConnection.Create(connectionSettings, new Uri("tcp://localhost:1113"));
await connection.ConnectAsync();
var eventData = new EventData(Guid.NewGuid(), "UserCreated", true, Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(user)), null);
await connection.AppendToStreamAsync("user-stream", ExpectedVersion.Any, eventData);
event-sourcing-examples:
@Autowired
private EventStore eventStore;
public void createUser(User user) {
eventStore.save(new Event("UserCreated", user));
}
Summary
EventStore is a robust, production-ready event sourcing solution with built-in features, while event-sourcing-examples provides a simpler, more flexible approach for learning and custom implementations. EventStore offers better scalability and language support but requires more setup. event-sourcing-examples is easier to get started with but may need additional work for production use.
Spring Boot helps you to create Spring-powered, production-grade applications and services with absolute minimum fuss.
Pros of Spring Boot
- Extensive ecosystem with a wide range of starter dependencies
- Robust auto-configuration capabilities for rapid development
- Large and active community support
Cons of Spring Boot
- Steeper learning curve for beginners
- Can be overkill for small, simple applications
- Potential for "magic" behavior due to auto-configuration
Code Comparison
Spring Boot:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Event Sourcing Examples:
public class OrderService {
@Autowired
private EventStore eventStore;
public void createOrder(CreateOrderCommand cmd) {
// Event sourcing logic
}
}
Spring Boot focuses on application bootstrapping and configuration, while Event Sourcing Examples demonstrates specific event sourcing patterns. Spring Boot provides a more comprehensive framework for building applications, whereas Event Sourcing Examples is tailored to showcase event sourcing concepts.
Spring Boot offers a broader range of features and integrations, making it suitable for various application types. Event Sourcing Examples, on the other hand, provides targeted examples for implementing event sourcing in Java applications, which can be valuable for developers specifically interested in this architectural pattern.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Event-Sourcing+CQRS example application
This example application is the money transfer application described in my talk Building and deploying microservices with event sourcing, CQRS and Docker. This talk describes a way of architecting highly scalable and available applications that is based on microservices, polyglot persistence, event sourcing (ES) and command query responsibility segregation (CQRS). Applications consist of loosely coupled components that communicate using events. These components can be deployed either as separate services or packaged as a monolithic application for simplified development and testing.
Built using the Eventuate platform
Read the overview or look at the other example applications.
Big ideas
This example illustrates several important concepts:
-
How to decompose an application into microservices - as described below the application consists of several services. For example, bank accounts are managed by one service, money transfers by another service.
-
Using an event-driven architecture to achieve data consistency - rather than using traditional distributed transaction to maintain database consistency this application uses an eventually consistent, event-driven approach.
-
Using event sourcing to implement the event-driven architecture - the domain logic consists of Domain-Driven Design (DDD) aggregates that using event sourcing.
-
Using Command Query Responsibility Segregation (CQRS) - update requests (HTTP POSTs and PUTs) and view requests (HTTP GETs) are handled by separate services.
-
How event sourcing enables deployment flexibility - the application can either be deployed as a monolith or as microservices.
About the example application
This example application provides a REST API for creating and viewing bank accounts and transferring money between them.
The following diagram shows the architecture:
There are the following services:
- Customers Service - REST API for creating customers
- Accounts Service - REST API for creating accounts
- Transactions Service - REST API for transferring money
- Customers View Service - subscribes to events and updates a MongoDB View, and provides an API for retrieving customers
- Accounts View Service - subscribes to events and updates a MongoDB View, and provides an API for retrieving accounts
There is also an API gateway service that acts as a Facade in front of the services.
About the examples
There are currently the following versions of the example application:
- java-spring - a Java and Spring Boot example
- scala-spring - a Scala and Spring Boot example (NOTE: this version is lagging the Java Spring and hasn't been updated in a longtime.)
Other examples will be added shortly including a Scala/Play example.
For more information, please see the wiki
About the Eventuate Platform
The application is built using Eventuate, which is an application platform for writing transactional microservices. It provides a simple yet powerful event-driven programming model that is based on event sourcing and Command Query Responsibility Segregation (CQRS). Eventuate solves the distributed data management problems inherent in a microservice architecture. It consists of a scalable, distributed event store and client libraries for various languages and frameworks including Java, Scala, and the Spring framework.
There are two versions of Eventuate:
- Eventuate SaaS server - this is a full featured event store that is hosted on AWS
- Eventuate Local - an open-source event store that is built using MySQL and Kafka
There is also an embedded test event store, which is great for integration tests.
Building and running the microservices
This is a Gradle project. However, you do not need to install Gradle since it will be downloaded automatically. You just need to have Java 8 installed.
The details of how to build and run the services depend slightly on whether you are using Eventuate SaaS or Eventuate Local.
Building and running using Eventuate SaaS
First, must sign up to get your credentials in order to get free access to the SaaS version.
Next, build the application
cd java-spring
./gradlew assemble
Next, you can launch the services using Docker Compose:
docker-compose up -d
Finally, you can open the home page, which is served up by the API Gateway: http://$DOCKER_HOST_IP:8080
Note: DOCKER_HOST_IP
is the IP address of the machine where Docker is running, e.g. the IP address of the VirtualBox VM.
Building and running using Eventuate Local
First, build the application
cd java-spring
./gradlew assemble -P eventuateDriver=local
Next, launch the services using Docker Compose:
export DOCKER_HOST_IP=...
docker-compose -f docker-compose-eventuate-local.yml up -d
Note: You need to set DOCKER_HOST_IP
before running Docker Compose.
This must be an IP address or resolvable hostname.
It cannot be localhost
.
See this guide to setting DOCKER_HOST_IP
for more information.
Finally, you can open the home page, which is served up by the API Gateway: http://$DOCKER_HOST_IP:8080
Top Related Projects
Framework for Evolutionary Message-Driven Microservices on the JVM
EventStoreDB, the event-native database. Designed for Event Sourcing, Event-Driven, and Microservices architectures
Spring Boot helps you to create Spring-powered, production-grade applications and services with absolute minimum fuss.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot