Microservices Online Shop
A senior developer discusses an open source project he as created that uses a microservices' based architecture to create a highly scalable experience.
Join the DZone community and get the full member experience.
Join For FreeThe Microservices Online Shop is an application with a modern software architecture that is cleanly designed and based on lightweight .NET technologies. The shop has two build variations. The first variant is the classic microservices architectural style. The second one is with Dapr. Dapr has a comprehensive infrastructure for building highly decoupled microservices; for this reason, I am using Dapr to build a highly scalable application with clean architecture and clean code.
Most of the work consists of creating the following services:
- The User Interface
- User Management Service
- Catalog Service
- Cart Service
- Order Service
Dapr is an event-driven, portable runtime for building microservices on the edge and in the cloud. This project is intended to show how you can make a clean microservices application with Dapr.
The project design decisions were made to balance realistic scenario and a simple demo showcase, but you have to make some other design decisions that fit better to your functional and non-functional requirements in the context of a real, working application.
The backend microservices are written in C#. However, Dapr is language-independent; you can change it to Java or Go, or any other programming language.
The front-end is written with Blazor. All APIs are REST APIs ( HTTP- and gRPC-based).
Project on GitHub: https://github.com/alugili/ModernArchitectureShop
Architecture Overview
Users Management Service (Identity Service)
This service provides a simple user management service to the modern shop and generates the bearer token. Only registered users can use the shop to place orders. This service is based on IdentityServer4.
Identityserver4 is an OpenID Connect and OAuth 2.0 framework for ASP.NET Core.
Store Service (Catalog/Product)
This service represents the online store that contains all the products and it allows the registered users to add/remove/update/get the products.
API routes:
/api/products?PageIndex={Page}&PageSize={PageSize} |
GET |
Get products |
/api/products/search-products?Filter={TextToSearch}&PageIndex={Page}&PageSize={PageSize} |
GET |
Search for text in all products |
Apart from the above functionality, each registered user can search and retrieve the store's products. The administrators can add/remove/update products (still in progress).
Store - Dapr Interaction
- Pub/Sub: Subscribes to the order-queue topic to receive new notifications from the order service.
- State Store: Only in the Dapr version
- Actor: StoreActor
- Bindings: Only in the Dapr version
Basket Service (Shopping Cart)
The basket service represents the Shopping Basket/Cart.
API routes:
/api/item/{basketItemJson} |
POST |
Post a new item and store it in the user basket |
/api/item/{Id} |
DELETE |
Delete the item with the given Id from the basket |
/api/items |
GET |
Get all items from the basket for the logged-in user |
The service is responsible for maintaining the user's shopping carts and persisting them. The submitted shopping cart is validated and then converted to an order. After that, the validated order is sent to the payment service for further processing.
Cart - Dapr Interaction
- Pub/Sub: Subscribes to the order's domain event to remove the working basket.
- State Store: Store the working basket.
- Actor: BasketActor.
Payment
Order Service
The order service allows you to put items in the Shopping Basket/Cart. It also allows the user to retrieve their order history.
API routes:
api/order/{basketItems} |
POST |
Place an order |
api/orders/completedorders?Username={_username} |
GET |
Get Order history for the user |
Store - Dapr Interaction
- Pub/Sub: The order service pushes items in shopping carts to the store-queue topic and to the payment topic to complete the order.
- State Store: Store the in-progress order.
- Actor: OrderActor.
- Bindings: Only in the Dapr version.
As you can see, most of the views are done! One important thing is still missing, and that is the payment service. I am using the Stripe API for this.
You can run the shop as a standalone service or on Docker containers. Kubernetes implementations are still under construction. I have tried to simplify the build by not using a build script. To do that, you have to follow the quickstart on GitHub.
If you want to join the GitHub project development process, you are welcome! Just send me a request, and you are welcome on board!
There is still a lot of work to be done in the following areas:
- Blazor UI
- IdentityServer 4
- Kubernetes
Clean Architecture
Clean Architecture is the key to loosely coupled applications. It allows you to decouple the application from the infrastructure completely.
Clean Architecture Separates
- User Interfaces
- Databases
- Use Cases
- Domains
Dependencies in the Microservices Online Shop
I have generated the architecture dependencies with Visual Studio 2019, and I have ordered them from the bottom to the top, as seen in the figure below.
Currently, I am using the fantastic tool “NDepend” to find code and architecture problems.
Clean Architecture in Microservices Online Shop
User interface
Store.UI is the front-end of the shop, and it contains the shop's user interface.
Database
Each service owns its database (StoreDb, BasketDb, OrderDb, UserDb).
Use Cases
I have also divided each domain service into four parts or assemblies:
- Business logic interfaces - Use cases: Contains the business logic interfaces; for example, StoreApplication.dll contains the interfaces for the Store service.
- Infrastructure: It contains the implementation of the use case or business logic.
- Domain: It contains the Domains entities or POCOs.
- API: It contains the Web API stuff.
I have tried to keep the code as compact and readable as possible. The core design concept is the separation of concerns in a clean way.
The Shop Software Architecture
Classic Architectural Style
In the classic architectural style, I am using the classic domain-driven design and microservices design. Here, each domain service is calling the other service directly (Web API)
Classic Architectural Style
Highly Scalable Design
I am using the Dapr infrastructure in this style. For example, I'm using RabbitMQ as the message bus, Redis for the state management, and some other Dapr functionalities which allow me to achieve a highly scalable architecture.
Highly Scalable Design
How Can You Test the Shop?
Build and Start the Shop
- Install the dotnet tool:
-
Shell
x
1install -g Microsoft.Tye --version "0.5.0-*" --add-source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5/nuget/v3/index.json
-
- Start tye-min.yaml in the console
-
Shell
x
1run tye-min.yaml
-
- Open the solution file ModernArchitectureShop.sln with the latest Visual Studio 2019 preview.
- Set the Startup projects as shown below:
- Press F5 and enjoy it!
QuickStart
QuickStart · alugili/ModernArchitectureShop Wiki (github.com)
Summary
Modern Architecture Shop is a clean, lightweight, and scalable .NET application. Keep your eye on the Road Map (watch it on GitHub). The next version contains features that will allow you to pay for an order with a Credit Card.
A shop manager service is also in the works, which will allow you to manage the shop's users, administrators, and products. Recommendation services and all other AI services or features will be provided later.
Opinions expressed by DZone contributors are their own.
Comments