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 and client-shell) and use reactive NoSQL database like Cassandra, MongoDB and Postgres.
-
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 BootShell Java application that has a couple of commands to interact withproduct-api,customer-apiandorder-api. The picture below show those commands.
-
Open a terminal and inside
spring-webflux-reactive-databasesroot folder rundocker-compose up -d -
Wait for Docker containers to be up and running. To check it, run
docker-compose ps
-
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 -
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
-
- 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
-
-
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) -
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)
-
-
- 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 | 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 |
Important: 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":"customer.a@test.com","city":"Berlin","street":"NYC Strasse","number":"123"} {"id":"2","name":"Customer B","email":"customer.b@test.com","city":"Berlin","street":"LA Strasse","number":"234"} {"id":"3","name":"Customer C","email":"customer.c@test.com","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-2create-order --customer-id 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": "customer.a@test.com", "city": "Berlin", "street": "NYC Strasse", "number": "123" } } -
To check how fast
order-apiget details about the customer and products of an order, create another order whereCustomer Aorder50random productscreate-order-random --customer-id 1 --num-products 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": "customer.a@test.com", "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 mongo use 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
\qto exit
- 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 docker-compose containers, network and volumes, go to a terminal and, inside
spring-webflux-reactive-databasesroot folder, run the command belowdocker-compose down -v
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
- Validate if customer and products exist before creating an order




