The goal of this project is to play with Axon
. For this, we will implement a food-ordering
app that consists of three Spring Boot
applications: customer-service
, restaurant-service
, and food-ordering-service
. These services were implemented with CQRS
and Event Sourcing
in mind. To achieve this, we used the Axon Framework
. The three services are connected to axon-server
, which is the Event Store
and Message Routing
solution used.
On ivangfr.github.io, I have compiled my Proof-of-Concepts (PoCs) and articles. You can easily search for the technology you are interested in by using the filter. Who knows, perhaps I have already implemented a PoC or written an article about what you are looking for.
-
Spring Boot
application that exposes a REST API to manageCustomers
. It also has a UI implemented usingJavaScript
,jQuery
, andSemantic UI
.customer-service
was implemented using theAxon Framework
. Every time a customer is added, updated, or deleted, the service emits the respective event, i.e.,CustomerAddedEvent
,CustomerUpdatedEvent
, orCustomerDeletedEvent
.customer-service
usesMySQL
to store customer data. Additionally, it listens to order events, collects the order information that it needs, and stores them in an order table present in its own database, so that it doesn't need to call another service to get this information. -
Spring Boot
application that exposes a REST API to manageRestaurants
. It also has a UI implemented usingJavaScript
,jQuery
, andSemantic UI
.restaurant-service
was implemented using theAxon Framework
. Every time a restaurant is added, updated, or deleted, the service emits the respective event, i.e.,RestaurantAddedEvent
,RestaurantUpdatedEvent
, orRestaurantDeletedEvent
. The same applies to the restaurant dishes, whose events are:RestaurantDishAddedEvent
,RestaurantDishUpdatedEvent
, orRestaurantDishDeletedEvent
.restaurant-service
usesPostgreSQL
to store restaurant/dish data. Additionally, it listens to order events, collects the order information that it needs, and stores them in an order table present in its own database, so that it doesn't need to call another service to get this information. -
Spring Boot
application that exposes a REST API to manageOrders
. It has a UI implemented usingJavaScript
,jQuery
, andSemantic UI
.food-ordering-service
was implemented using theAxon Framework
. Every time an order is created, the service emits the respective event, i.e.,OrderCreatedEvent
.food-ordering-service
usesMongoDB
to store order data. Additionally, it listens to customer and restaurant/dish events, collects the information that it needs, and stores them in a customer or restaurant/dish table present in its own database, so that it doesn't need to call another service to get this information. -
Maven
project where all events mentioned above are defined. It generates a JAR file that is added as a dependency in thepom.xml
ofcustomer-service
,restaurant-service
, andfood-ordering-service
.
-
Open a terminal and inside the
axon-springboot-websocket
root folder run:docker compose up -d
-
Wait for Docker containers to be up and running. To check it, run:
docker ps -a
Inside the axon-springboot-websocket
root folder, run the following commands in different terminals:
-
axon-event-commons
./mvnw clean install --projects axon-event-commons
-
customer-service
./mvnw clean spring-boot:run --projects customer-service -Dspring-boot.run.jvmArguments="-Dserver.port=9080"
-
restaurant-service
./mvnw clean spring-boot:run --projects restaurant-service -Dspring-boot.run.jvmArguments="-Dserver.port=9081"
-
food-ordering-service
./mvnw clean spring-boot:run --projects food-ordering-service -Dspring-boot.run.jvmArguments="-Dserver.port=9082"
-
- In a terminal, make sure you are in the
axon-springboot-websocket
root folder; - Run the following script to build the Docker images:
./build-docker-images.sh
- In a terminal, make sure you are in the
-
-
customer-service
Environment Variable Description MYSQL_HOST
Specify the host of the MySQL
database to use (defaultlocalhost
)MYSQL_PORT
Specify the port of the MySQL
database to use (default3306
)AXON_SERVER_HOST
Specify the host of the Axon Server
to use (defaultlocalhost
)AXON_SERVER_PORT
Specify the port of the Axon Server
to use (default8124
) -
restaurant-service
Environment Variable Description POSTGRES_HOST
Specify the host of the Postgres
database to use (defaultlocalhost
)POSTGRES_PORT
Specify the port of the Postgres
database to use (default5432
)AXON_SERVER_HOST
Specify the host of the Axon Server
to use (defaultlocalhost
)AXON_SERVER_PORT
Specify the port of the Axon Server
to use (default8124
) -
food-ordering-service
Environment Variable Description MONGODB_HOST
Specify the host of the Mongo
database to use (defaultlocalhost
)MONGODB_PORT
Specify the port of the Mongo
database to use (default27017
)AXON_SERVER_HOST
Specify the host of the Axon Server
to use (defaultlocalhost
)AXON_SERVER_PORT
Specify the port of the Axon Server
to use (default8124
)
-
-
- In a terminal, make sure you are inside the
axon-springboot-websocket
root folder; - Run the following command:
./start-apps.sh
- In a terminal, make sure you are inside the
Application | URL | Swagger |
---|---|---|
customer-service | http://localhost:9080 | http://localhost:9080/swagger-ui.html |
restaurant-service | http://localhost:9081 | http://localhost:9081/swagger-ui.html |
food-ordering-service | http://localhost:9082 | http://localhost:9082/swagger-ui.html |
The GIF below shows a user creating a customer in the customer-service
UI. Then, in the restaurant-service
UI, they create a restaurant and add a dish. Finally, using the food-ordering-service
UI, they submit an order using the customer and restaurant/dish created. Note that as soon as a customer or restaurant/dish is created, an event is sent, and the consumer of this event updates its UI in real-time using WebSockets.
-
Axon Server
The
Axon Server
dashboard can be accessed at http://localhost:8024 -
MySQL
docker exec -it -e MYSQL_PWD=secret mysql mysql -uroot --database customerdb SELECT * FROM customers; SELECT * FROM orders;
Type
exit
to exit -
PostgreSQL
docker exec -it postgres psql -U postgres -d restaurantdb SELECT * FROM restaurants; SELECT * FROM dishes; SELECT * FROM orders;
Type
\q
to exit -
MongoDB
docker exec -it mongodb mongo foodorderingdb db.customers.find() db.restaurants.find() db.orders.find()
Type
exit
to exit
- To stop applications:
- If you start them with
Maven
, go to the terminals where they are running and pressCtrl+C
; - If you start them as Docker containers, make sure you are inside the
axon-springboot-websocket
root folder and run the following script:./stop-apps.sh
- If you start them with
- To stop and remove docker compose containers, network, and volumes, go to a terminal and, inside the
axon-springboot-websocket
root folder, run the command below:docker compose down -v
To remove the docker images created by this project, go to a terminal and, inside the axon-springboot-websocket
root folder, run the following script:
./remove-docker-images.sh