spring-webflux-reactive-databases
spring-webflux-reactive-databases copied to clipboard
The goal of this project is to play with Spring WebFlux on client and server side. For it, we will implement some Spring Boot Java Web applications, product-api, customer-api, order-api and client-she...
spring-webflux-reactive-databases
The goal of this project is to play with Spring WebFlux both on client and server side. For it, we will implement Spring Boot Java Web applications (product-api, customer-api, order-api, notification-api and client-shell) and use different databases like Cassandra, MongoDB, Postgres and MySQL.
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 Architecture

Applications
-
product-api
Spring BootJava Web application that exposes a REST API to manageproducts. It usesMongoDBas storage.
-
customer-api
Spring BootJava Web application that exposes a REST API to managecustomers. It usesPostgresas storage.
-
order-api
Spring BootWeb Java application that exposes a REST API to manageorders. It usesCassandraas storage. In order to get more information about anorder, i.e, thenameof the customer who placed it or thenameorpriceof the products in the order,order-apiusesWebClientandCompletableFutureto fetch this information fromcustomer-apiandproduct-api.
-
notification-api
Spring BootWeb Java application that exposes a REST API to managenotifications.
-
client-shell
Spring BootShell Java application that has a couple of commands to interact withproduct-api,customer-api,order-apiandnotification-api. The picture below show those commands.
Prerequisites
Initialize Environment
-
Open a terminal and inside
spring-webflux-reactive-databasesroot folder run./init-environment.sh -
Wait for the script to finish
Run applications with Maven
-
product-api
Open a new terminal and, inside
spring-webflux-reactive-databasesroot folder, run the following command./mvnw clean spring-boot:run --projects product-api -
customer-api
Open a new terminal and, inside
spring-webflux-reactive-databasesroot folder, run the following command./mvnw clean spring-boot:run --projects customer-api -
order-api
Open a new terminal and, inside
spring-webflux-reactive-databasesroot folder, run the following command./mvnw clean spring-boot:run --projects order-api -
notification-api
Open a new terminal and, inside
spring-webflux-reactive-databasesroot folder, run the following command./mvnw clean spring-boot:run --projects notification-api -
client-shell
Open a new terminal and, inside
spring-webflux-reactive-databasesroot folder, run the following command to build the executable jar file./mvnw clean package --projects client-shell -DskipTestsTo start
client-shellrun./client-shell/target/client-shell-1.0.0.jar
Run applications as Docker containers
-
Build Docker Images
- In a terminal, make sure you are in
spring-webflux-reactive-databasesroot 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
-
product-api
Environment Variable Description MONGODB_HOSTSpecify host of the Mongodatabase to use (defaultlocalhost)MONGODB_PORTSpecify port of the Mongodatabase to use (default27017) -
customer-api
Environment Variable Description POSTGRES_HOSTSpecify host of the Postgresdatabase to use (defaultlocalhost)POSTGRES_PORTSpecify port of the Postgresdatabase to use (default5432) -
order-api
Environment Variable Description CASSANDRA_HOSTSpecify host of the Cassandradatabase to use (defaultlocalhost)CASSANDRA_PORTSpecify port of the Cassandradatabase to use (default9042)PRODUCT_API_HOSTSpecify host of the product-apito use (defaultlocalhost)PRODUCT_API_PORTSpecify port of the product-apito use (default9080)CUSTOMER_API_HOSTSpecify host of the customer-apito use (defaultlocalhost)CUSTOMER_API_PORTSpecify port of the customer-apito use (default9081) -
notification-api
Environment Variable Description MYSQL_HOSTSpecify host of the MySQLdatabase to use (defaultlocalhost)MYSQL_PORTSpecify port of the MySQLdatabase to use (default3306)CUSTOMER_API_HOSTSpecify host of the customer-apito use (defaultlocalhost)CUSTOMER_API_PORTSpecify port of the customer-apito use (default9081)ORDER_API_HOSTSpecify host of the order-apito use (defaultlocalhost)ORDER_API_PORTSpecify port of the order-apito use (default9082) -
client-shell
Environment Variable Description PRODUCT_API_HOSTSpecify host of the product-apito use (defaultlocalhost)PRODUCT_API_PORTSpecify port of the product-apito use (default9080)CUSTOMER_API_HOSTSpecify host of the customer-apito use (defaultlocalhost)CUSTOMER_API_PORTSpecify port of the customer-apito use (default9081)ORDER_API_HOSTSpecify host of the order-apito use (defaultlocalhost)ORDER_API_PORTSpecify port of the order-apito use (default9082)NOTIFICATION_API_HOSTSpecify host of the notification-apito use (defaultlocalhost)NOTIFICATION_API_PORTSpecify port of the notification-apito use (default9083)
-
-
Start Docker Containers
- In a terminal, make sure you are inside
spring-webflux-reactive-databasesroot folder - Run following command
./start-apis.sh && ./start-shell.sh
- In a terminal, make sure you are inside
Application's URL
| Application | URL |
|---|---|
| product-api | http://localhost:9080/swagger-ui.html |
| customer-api | http://localhost:9081/swagger-ui.html |
| order-api | http://localhost:9082/swagger-ui.html |
| notification-api | http://localhost:9083/swagger-ui.html |
Playing around
Warning: the ids shown below will be different when you run it
-
In
client-shellterminal, import some products and customers by running the following command- If you are running using
Mavenscript ../src/main/resources/samples.txt - If you are running as Docker container
script /app/resources/samples.txt
- If you are running using
-
Get all customer
get-customersIt should return
{"id":"1","name":"Customer A","email":"[email protected]","city":"Berlin","street":"NYC Strasse","number":"123"} {"id":"2","name":"Customer B","email":"[email protected]","city":"Berlin","street":"LA Strasse","number":"234"} {"id":"3","name":"Customer C","email":"[email protected]","city":"Berlin","street":"DC Strasse","number":"345"} ... -
Get all products
get-productsIt should return
{"id":"5ee3ee31b460d868af49f389","name":"product-1","price":199.99} {"id":"5ee3ee32b460d868af49f38a","name":"product-2","price":299.99} ... -
Create an order where
Customer Abuys1 unitofproduct-1and2 unitsofproduct-2Warning: the product ids informed here are just a sample. You will have different ones.
create-order --customerId 1 --products 5ee3ee31b460d868af49f389:1;5ee3ee32b460d868af49f38a:2It should return
{ "orderId":"5aaad64c-4e80-48e0-926d-8f1b7027955a", "status":"OPEN", "created":"2020-06-12T22:09:59.558232", "products": [ {"id":"5ee3ee31b460d868af49f389", "quantity":1}, {"id":"5ee3ee32b460d868af49f38a", "quantity":2} ], "customerId":"1" } -
Get details about the order created
get-order-detailed 5aaad64c-4e80-48e0-926d-8f1b7027955aIt should return
{ "orderId":"5aaad64c-4e80-48e0-926d-8f1b7027955a", "status":"OPEN", "created":"2020-06-12T22:09:59.558", "products": [ {"id":"5ee3ee32b460d868af49f38a", "name":"product-2", "quantity":2, "price":299.99}, {"id":"5ee3ee31b460d868af49f389", "name":"product-1", "quantity":1, "price":199.99} ], "customer": { "id":"1", "name":"Customer A", "email":"[email protected]", "city":"Berlin", "street":"NYC Strasse", "number":"123" } } -
To create a notification to the order created above
create-notification 5aaad64c-4e80-48e0-926d-8f1b7027955a -
To check how fast
order-apiget details about the customer and products of an order, create another order whereCustomer Aorder50random productscreate-order-random --customerId 1 --numProducts 50It should return
{ "orderId":"87133d36-67f0-4388-b15b-7d66ad739374", "status":"OPEN", "created":"2020-06-12T22:14:08.342338", "products": [ {"id":"5ee3ee32b460d868af49f38a", "quantity":4}, ... {"id":"5ee3ee32b460d868af49f396", "quantity":3} ], "customerId":"1" } -
In another terminal, to get the details of the order previously created and the response time of this call, we are using
order-api's endpointGET /api/orders/{orderId}/detailedcurl -w "\n\nResponse Time: %{time_total}s" -s localhost:9082/api/orders/87133d36-67f0-4388-b15b-7d66ad739374/detailedIt will return something like
{ "orderId":"87133d36-67f0-4388-b15b-7d66ad739374", "status":"OPEN", "created":"2020-06-12T22:14:08.342338", "products": [ {"id":"5ee3ee32b460d868af49f395", "name":"product-13", "quantity":4, "price":1399.99}, ... ], "customer": { "id":"1", "name":"Customer A", "email":"[email protected]", "city":"Berlin", "street":"NYC Strasse", "number":"123" } } Response Time: 0.292698s
Useful Commands
-
Cassandra
docker exec -it cassandra cqlsh USE mycompany; SELECT * FROM orders;Type
exitto get out ofcqlsh -
MongoDB
docker exec -it mongodb mongosh productdb db.products.find()Type
exitto get out ofMongoDB shell -
Postgres
docker exec -it postgres psql -U postgres -d customerdb \dt customer SELECT * FROM CUSTOMER;Type
exitto get out ofpsql -
MySQL
docker exec -it -e MYSQL_PWD=secret mysql mysql -uroot --database notificationdb SELECT * FROM notification;Type
exitto get out ofMySQL monitor
Shutdown
- To stop
client-shell, go to the terminal where it is running and typeexit - To stop
product-api,customer-apiandorder-api- If you start them with
Maven, go to the terminals were they are running and pressCtrl+C - If you start them as Docker containers, go to a terminal and, inside
spring-webflux-reactive-databasesroot folder, run the following script./stop-apis.sh
- If you start them with
- To stop and remove the database containers, network and volumes, go to a terminal and, inside
spring-webflux-reactive-databasesroot folder, run the script below./shutdown-environment.sh
Cleanup
To remove all Docker images created by this project, go to a terminal and, inside spring-webflux-reactive-databases root folder, run the following script
./remove-docker-images.sh
References
- https://projectreactor.io/docs/core/release/reference/