- Notifications
You must be signed in to change notification settings - Fork309
An example of Choreography-based sagas in Spring Boot/JPA microservices
License
eventuate-tram/eventuate-tram-examples-customers-and-orders
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
This project is part ofEventuate, which is a microservices collaboration platform.
This application demonstrates two key patterns:
The application consists of three services:
Order Service- manages ordersCustomer Service- manages customersOrder History Service- maintains the order history
All services are implemented using Spring Boot, JPA and theEventuate Tram framework, which provides transactional publish/subscribe.
TheOrder Service uses a choreography-based saga to enforce the customer’s credit limit when creating orders.
TheOrder History Service implements a CQRS view and subscribes to domain events published by theOrder Service andCustomer Service
Scroll down to get a tour of a code within a Github Codespace or Visual Studio Code.
Sagas are a mechanism for maintaining data consistency in amicroservice architecture.A saga is a sequence of transactions, each of which is local to a service.
There are two main ways to coordinate sagas: orchestration and choreography.This example uses choreography-based sagas, which use domain events for coordination.Each step of a saga updates the local database and publishes a domain event.The domain event is processed by an event handler, which performs the next local transaction.
To learn more about why you need sagas if you are using microservices:
Look at theOrchestration-based saga example
Read theSaga pattern
Look atMicroCPH 2019 presentation
Read about sagas in myMicroservices patterns book
The saga for creating anOrder consists of the follow steps:
The Order Service creates an
Orderin aPENDINGstate and publishes anOrderCreatedeventThe
Customer Servicereceives the event attempts to reserve credit for thatOrder. It publishes either aCredit Reservedevent or aCreditLimitExceededevent.The
Order Servicereceives the event and changes the state of the order to eitherAPPROVEDorREJECTED.
TheCQRS pattern implements queries that retrieves data from multiple services.It maintains a queryable replica of the data by subscribing to domain events published by the services that own the data.
In this example, theOrder History Service maintains a CQRS view in MongoDB by subscribing to domain events published by theOrder Service andCustomer Service.The CQRS view stores each customer as a MongoDB document that contains information the customer and their orders.
To learn more about why you need CQRS if you are using microservices:
Read theCQRS pattern
Read about CQRS in myMicroservices patterns book
The services uses theEventuate Tram framework to communicate asynchronously using events.The flow for publishing a domain event using Eventuate Tram is as follows:
Eventuate Tram inserts events into the
MESSAGEtable as part of the ACID transaction that updates the JPA entity.The Eventuate Tram CDC service tracks inserts into the
MESSAGEtable using the MySQL binlog (or Postgres WAL) and publishes messages to Apache Kafka.A service subscribes to the events, updates its database, and possibly publishes more events.
The following diagram shows the architecture of the Customers and Orders application.
The application consists of three services:Customer Service,Order Service, andOrder History Service
TheCustomer Service implements a REST API for managing customers.The service persists theCustomer JPA entity in a MySQL/MsSQL/Postgres database.UsingEventuate Tram, it publishesCustomer domain events that are consumed by theOrder Service.
For more information, see themicroservice canvas for theCustomer Service.
TheOrder Service implements REST API for managing orders.The service persists theOrder JPA entity in MySQL/MsSQL/Postgres database.UsingEventuate Tram, it publishesOrder domain events that are consumed by theCustomer Service.
For more information, see themicroservice canvas for theOrder Service.
TheOrder History Service implements REST API for querying a customer’s order historyThis service subscribes to events published by theOrder Service andCustomer Service and updates a MongoDB-based CQRS view.
For more information, see themicroservice canvas for theOrder History Service.
Start the application and the required infrastructure services by running either
./gradlew :end-to-end-tests:runApplicationMySQLor
./gradlew :end-to-end-tests:runApplicationPostgresThis command starts the containers on unique ports.It prints out the home page URL.
There are a couple of ways to interact with the application: using the Swagger UIs or usingcurl.Once the application has started, visit the home page URL to see the URLs for the Swagger UIs and the API Gateway.
You can also usecurl to interact with the services via theAPI Gateway - note you need to replace port 8080 with the correct port for theAPI Gateway.
First, let’s create a customer:
$ curl -X POST --header"Content-Type: application/json" -d'{ "creditLimit": { "amount": 5 }, "name": "Jane Doe"}' http://localhost:8080/customersHTTP/1.1 200Content-Type: application/json;charset=UTF-8{"customerId": 1}
Next, create an order:
$ curl -X POST --header"Content-Type: application/json" -d'{ "customerId": 1, "orderTotal": { "amount": 4 }}' http://localhost:8080/ordersHTTP/1.1 200Content-Type: application/json;charset=UTF-8{"orderId": 1}
Next, check the status of theOrder:
$ curl -X GET http://localhost:8080/orders/1HTTP/1.1 200Content-Type: application/json;charset=UTF-8{"orderId": 1,"orderState":"APPROVED"}
Finally, look at the customer’s order history in theOrder History Service:
$ curl -X GET --header"Accept: */*""http://localhost:8080/customers/1/orderhistory"HTTP/1.1 200Content-Type: application/json;charset=UTF-8{"id": 1,"orders": {"1": {"state":"APPROVED","orderTotal": {"amount": 4 } } },"name":"Chris","creditLimit": {"amount": 100 }}
I’ve configured aCode Tour that will walk through the code in either Visual Studio Code or Github Codespaces.
If necessary, install the Code Tour extension from the Visual Studio Code Marketplace.
Use the
CodeTour: Start Tourcommand from the command palette to start the tour.
- Create a codespace.
- If necessary, install the Code Tour extension from the Visual Studio Code Marketplace.
- Use the
CodeTour: Start Tourcommand from the command palette to start the tour.
Don’t hesitate to create an issue or see
About
An example of Choreography-based sagas in Spring Boot/JPA microservices
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.




