axon-springboot-websocket
axon-springboot-websocket copied to clipboard
The goal is to explore Axon. We will develop a food-ordering app comprising 3 Spring Boot applications: customer-service, restaurant-service, and food-ordering-service. These services are implemented...
axon-springboot-websocket
The goal of this project is play with Axon. For it, 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 so, in order to achieve it, we used Axon Framework. The three services are connected to axon-server that is the Event Store and Message Routing solution used.
Proof-of-Concepts & Articles
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.
Project Diagram

Applications
-
customer-service
Spring Bootapplication that exposes a REST API to manageCustomers. It also has a UI implemented usingJavascript,JQueryandSemantic UI.
customer-servicewas implemented usingAxon Framework. Everytime a customer is added, updated or deleted, the service emits the respective event, i.e,CustomerAddedEvent,CustomerUpdatedEventorCustomerDeletedEvent.customer-serviceusesMySQLto store customer's data. Besides, 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. -
restaurant-service
Spring Bootapplication that exposes a REST API to manageRestaurants. It also has a UI implemented usingJavascript,JQueryandSemantic UI.
restaurant-servicewas implemented usingAxon Framework. Everytime a restaurant is added, updated or deleted, the service emits the respective event, i.e,RestaurantAddedEvent,RestaurantUpdatedEventorRestaurantDeletedEvent. The same applies to the restaurant dishes, whose events are:RestaurantDishAddedEvent,RestaurantDishUpdatedEventorRestaurantDishDeletedEventrestaurant-serviceusesPostgreSQLto store restaurant/dish data. Besides, 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. -
food-ordering-service
Spring Bootapplication that exposes a REST API to manageOrders. It has a UI implemented usingJavascript,JQueryandSemantic UI.
food-ordering-servicewas implemented usingAxon Framework. Everytime an order is created, the service emits the respective event, i.e,OrderCreatedEvent.food-ordering-serviceusesMongoDBto store order data. Besides, 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 this own database, so that it doesn't need to call another service to get this information. -
axon-event-commons
Mavenproject where all events mentioned above are defined. It generates a JAR file that is added as a dependency in thepom.xmlofcustomer-service,restaurant-serviceandfood-ordering-service.
Prerequisites
Start Environment
-
Open a terminal and inside
axon-springboot-websocketroot folder rundocker compose up -d -
Wait for Docker containers to be up and running. To check it, run
docker compose ps
Running applications with Maven
Inside 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"
Running applications as Docker containers
-
Build Docker images
- In a terminal, make sure you are in
axon-springboot-websocketroot folder - Run the following script to build the Docker images
- JVM
./docker-build.sh - Native (it's not implemented yet)
./docker-build.sh native
- JVM
- In a terminal, make sure you are in
-
Environment Variables
-
customer-service
Environment Variable Description MYSQL_HOSTSpecify host of the MySQLdatabase to use (defaultlocalhost)MYSQL_PORTSpecify port of the MySQLdatabase to use (default3306)AXON_SERVER_HOSTSpecify host of the Axon Serverto use (defaultlocalhost)AXON_SERVER_PORTSpecify port of the Axon Serverto use (default8124) -
restaurant-service
Environment Variable Description POSTGRES_HOSTSpecify host of the Postgresdatabase to use (defaultlocalhost)POSTGRES_PORTSpecify port of the Postgresdatabase to use (default5432)AXON_SERVER_HOSTSpecify host of the Axon Serverto use (defaultlocalhost)AXON_SERVER_PORTSpecify port of the Axon Serverto use (default8124) -
food-ordering-service
Environment Variable Description MONGODB_HOSTSpecify host of the Mongodatabase to use (defaultlocalhost)MONGODB_PORTSpecify port of the Mongodatabase to use (default27017)AXON_SERVER_HOSTSpecify host of the Axon Serverto use (defaultlocalhost)AXON_SERVER_PORTSpecify port of the Axon Serverto use (default8124)
-
-
Start Docker containers
- In a terminal, make sure you are inside
axon-springboot-websocketroot folder - Run following command
./start-apps.sh
- In a terminal, make sure you are inside
Application URLs
| 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 |
Demo
The GIF below shows a user creating a customer in customer-service UI. Then, in restaurant-service UI, he creates a restaurant and adds a dish. Finally, using food-ordering-service UI, he submits 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 realtime using WebSockets.

Useful Commands & Links
-
Axon Server
Axon Serverdashboard 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
exitto exit -
PostgreSQL
docker exec -it postgres psql -U postgres -d restaurantdb SELECT * FROM restaurants; SELECT * FROM dishes; SELECT * FROM orders;Type
\qto exit -
MongoDB
docker exec -it mongodb mongo foodorderingdb db.customers.find() db.restaurants.find() db.orders.find()Type
exitto exit
Shutdown
- 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
axon-springboot-websocketroot 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
axon-springboot-websocketroot folder, run the command belowdocker compose down -v
Cleanup
To remove the docker images created by this project, go to a terminal and, inside axon-springboot-websocket root folder, run the following script
./remove-docker-images.sh
References
- https://sgitario.github.io/axon-by-example/
- https://blog.nebrass.fr/playing-with-cqrs-and-event-sourcing-in-spring-boot-and-axon/