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




