This project is building ecommerce full application includes client side using ReactJS and server side using Microservices architecture with FastAPI and Redis as a database. There are two microservices, one for products and the other for orders. I used Redis Stream as message broker among microservices and Redis database.
sequenceDiagram
par Client to Microservice-Payment
Client->>Microservice-Payment: Place an order for the items
and Client to Microservice-Inventory
Client->>Microservice-Inventory: Search and browse the products
end
Microservice-Payment-->>Client: Retrieve client's order details
Microservice-Inventory-->>Client: Retrieve the details of the products
Microservice-Payment ->> Microservice-Inventory: Update the Inventory
- ✅ FastAPI
- ✅ Microservices
- ✅ Redis-om
- ✅ Redis-Stream
- ✅ React
- ✅ TypeScript
- ✅ Vite
- ✅ React-Router-Dom
- ✅ Bootstrap-Dashboard
In invertory-microservice directory run the following command:
uvicorn main:app --reload
In payment-microservice directory run the following command:
uvicorn main:app --reload --port=8001
(Redis Stream) Turn on Redis server in inventory-microservice and payment-microservice directories:
python consumer.py
- FASTAPI.BACKGROUND TASKS is used to run a function in the background. It is useful for tasks that need to run after a request, but that the client doesn't really have to be waiting for the result. What is different between Background task and message queue, is that background task is not persistent, it will be lost if the server is restarted. So, it is not suitable for long running tasks. For long running tasks, we need to use message queue.
- Some workflows for MVC.
- POST and GET a new product
http://localhost:8000/products/
- POST and GET a new product
{
"id": "01H28HATR7JG2YBH22ABPJWW33",
"name": "product",
"price": 20.0,
"quantity": 100
}
Order this product id in http://localhost:8001/orders/
{
"id": "01H28HATR7JG2YBH22ABPJWW33",
"quantity": 10
}
{
"pk": "01H28HDT0QXZKAE3F49HPJNN99",
"product_id": "01H28HATR7JG2YBH22ABPJWW33",
"price": 20.0,
"fee": 4.0,
"total": 24.0,
"quantity": 10,
"status": "pending"
}
- In 5 second, the product was delete in inventory DELETE
localhost:8000/products/01H28HATR7JG2YBH22ABPJWW33
- Copy
pk
from order response and GEThttp://localhost:8001/orders/01H28HDT0QXZKAE3F49HPJNN99
{
"pk": "01H28HDT0QXZKAE3F49HPJNN99",
"product_id": "01H28HATR7JG2YBH22ABPJWW33",
"price": 20.0,
"fee": 4.0,
"total": 24.0,
"quantity": 10,
"status": "refunded"
}
Status changed to refunded because the product was deleted in inventory, there is time limit setting for this case.
- Initial setup for ReactTS (frontend).
Change the following in tsconfig.json, and remove
"allowImportingTsExtensions": true,
/* Bundler mode */
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
And tsconfig.node.json file, changed the following:
"moduleResolution": "node16",
4.Microservices architecture for frontend building. I should build two frontend React apps, one for inventory and the other for payment. But for this demo, I used one proxy to create two services connection. In real world, we should use two frontend apps.
server: {
proxy: {
"/api": {
target: "http://127.0.0.1:8000",
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ""),
},
"/app": {
target: "http://127.0.0.1:8001",
changeOrigin: true,
rewrite: (path) => path.replace(/^\/app/, ""),
},
💖 Hope this project can help you to understand Microservices architecture and Redis Stream. If you like it, please give me a star ✨. I need your support to keep going. Thank you so much! 💖