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.
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 BootJava Web application that exposes a REST API to manageproducts. It usesMongoDBas storage.
- 
Spring BootJava Web application that exposes a REST API to managecustomers. It usesPostgresas storage.
- 
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.
- 
Spring BootWeb Java application that exposes a REST API to managenotifications.
- 
Spring BootShell Java application that has a couple of commands to interact withproduct-api,customer-api,order-apiandnotification-api. The picture below shows those commands.
- 
Open a terminal and inside the spring-webflux-reactive-databasesroot folder, run./init-environment.sh 
- 
Wait for the script to finish. 
- 
product-api Open a new terminal and, inside the 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 the 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 the 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 the 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 the spring-webflux-reactive-databasesroot folder, run the following command to build the executable jar file./mvnw clean package --projects client-shell -DskipTests To start client-shell, run:./client-shell/target/client-shell-1.0.0.jar 
- 
- In a terminal, make sure you are in the spring-webflux-reactive-databasesroot folder/
- Run the following script to build the Docker images:
./build-docker-images.sh 
 
- In a terminal, make sure you are in the 
- 
- 
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)
 
- 
- 
- In a terminal, make sure you are inside the spring-webflux-reactive-databasesroot folder.
- Run following command:
./start-apis.sh && ./start-shell.sh
 
- In a terminal, make sure you are inside the 
| 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 | 
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 Maven:script ../src/main/resources/samples.txt 
- If you are running as Docker container:
script /workspace/BOOT-INF/classes/samples.txt 
 
- If you are running using 
- 
Get all customers get-customers It 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-products It 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-8f1b7027955a It 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 for 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 50 It 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 previously created order and the response time of this call, use 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
- 
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
- To stop client-shell, go to the terminal where it is running and typeexit.
- To stop product-api,customer-api, andorder-api:- If you start them with Maven, go to the terminals where they are running and pressCtrl+C.
- If you start them as Docker containers, go to a terminal and, inside the 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 the spring-webflux-reactive-databasesroot folder, run the script below:./shutdown-environment.sh 
To remove all Docker images created by this project, go to a terminal and, inside the spring-webflux-reactive-databases root folder, run the following script:
./remove-docker-images.sh




