This is the result of my study on Microservices. It is an online shopping system and the details are here: https://lain.run/projects/Microservices/.
- Microservices pattern
- CQRS
- Event Bus
- Event Store
- Database per Service
- Event Broker Pattern
- Saga - Choreography
- Reverse Proxy
- RESTful services
Template: As a [ USER ] I want to [ ACTION ] So that [ REASONING ]
User Personas:
- Customer
- Product Manager
Features:
- View Products
- Shop
- View Order Status
- View User Profile
- Get Invoice
- Modify products, prices, stocks
- Modify user credits
User Story | Acceptance Criteria |
---|---|
As a customer, I want to browse for products so that I can place an order. | View product categories View Products Ability to order each product Get an Invoice |
As a customer, I want to view my past orders so that it guides my future purposes. | View orders. Display order status, product info, order date |
As a customer, I want to view my profile information so that I can make adjustments. | View user information and credit Edit name, password, email |
As a product manager, I want to add/edit/delete products so that customers can buy them | View/Add/Edit/Delete products. Names, prices, suppliers, units in stock |
As a product manager, I want to view all customer order states so that I can assist if needed | View all orders and their states history in the system |
As a product manager, I want to edit customer credit so that they can purchase products | View all users and their credit Edit credits |
I used Python with Flask often because it is arguably one of the fastest and cleanest ways to prototype anything. I would implement everything in Python if I didn't want to introduce some variety. For Event Store, I used two docker containers. SDK to build for Linux, Runtime for deployment.
Module | Category | Programming Language | Sdk | Docker |
---|---|---|---|---|
ECommerce Website | Consumer | Python | Flask | python:alpine |
Manager Website | Consumer | Python | Flask | python:alpine |
Native Android Application | Consumer | Java | Android SDK | - |
Accounting Database | Database | - | - | couchdb:latest |
Customer Database | Database | - | - | redis:alpine |
Event Store Database | Database | - | - | mongo mongo-express |
Order Database | Database | - | - | postgres:alpine |
Event Bus | Support Tool | - | - | rabbitmq:management |
Event Store | Support Tool | C# | .NET Core 2.1 | dotnet:2.1-sdk-alpine dotnet:2.1-aspnetcore-runtime-alpine |
Reverse Proxy | Support Tool | - | - | nginx:alpine |
Accounting Web Service | Web Service | Javascript | Node | node:alpine |
Customer Web Service | Web Service | Python | Flask | python:alpine |
Order Web Service | Web Service | Java | JDK-Jersey | maven:3.6-jdk-8-alpine |
Product Web Service | Web Service | Python | Flask | python:alpine |
Api by service;
Customer (Python) | Order Service(Java) | Product Service(Python) | Accounting Service(JS) |
---|---|---|---|
login-user | place-order | get-products | get-revenue |
add-user | get-orders | get-all-products | |
update-user | get-product-details | ||
get-user | add-new-product | ||
get-all-users | update-product | ||
get-credit | delete-product | ||
set-credit | get-categories | ||
add-new-category | |||
update-category | |||
delete-category |
As follows;
The only Saga sample. Occurs when user places an order request for a product. Not all rollbacks are implemented. It looks messy but what happens here is: Customer places an order, If the customer has enough credit for the product price and if the product is in stock, the order succeeds.
All modules are prepared for Docker Compose. You need to create Docker networks written inside docker compose files, then run the compose files. The classic option is running compose from terminal. You need to repeat the following process for each module.
- Open a terminal. Change directory to the module
- Type
docker-compose up
That's it. Everything should install inside its own container and run in there. Aside from Docker itself, you don't need to explicitly install anything else.
Only couchDB requires the following command after it starts:
curl -X PUT http://accounting_usr:[email protected]:5984/_users
Both websites run on ports 5001 and 5002 both of which you can edit from their yml files. On Android project, you need to open the settings (upper right corner) inside the app and change the IP / Host of the reverse proxy server.
MIT
Ayhan AVCI 2018