In earlier post, I shared some fundamentals about microservices concepts, and how to get started with! Now we learn with some real-time microservices development with examples.
Here we design a order management system Microservices, which is a combination of multiple services within it. We design the whole system as per microservices design principal, at the time of designing and development you must realize how microservices is surely the better option compare to designing a big enterprise solution, and why microservices architecture is becoming more popular and successful to address constantly changing business demand.
Note: In this article I will focus more on microservices design best practices and how to implement few microservices specific design patterns with real-time example, so I more talk about design rather than implementation, and I will skip few basic implementation questions here; but you can check those queries in my earlier post asp.net core 3.1 web api example.
Here are some core principles we follow while designing each micro service
Let’s understand how we can implement CQRS (Command Query Responsibility Segregation) design pattern in every service. Now to standardize every service design we add two interface called ICommandService and IQueryService (you can give any other meaningful name)
Now let us build a quick microservices solution using asp.net core considering CQRS pattern, as you can see in following I have five microservices in my solution, and the expanded order service displaying Command and Query segregation approach
public interface ICommandService { Task CreateOreder(Order order,List<OrderItem> items); Task CancelOrder(long orderId,string reason); }
Whenever some order created or order cancelled, the order service table in order database gets updated, ideally every microservice should have its own database (database per service concept), then you probably have question how to maintain data consistency with other service databases!
Yes, with using single RDBMS that could have been much easier, and obviously will be a very complicated and challenging task to maintain data consistency among multiple databases of other services.
In microservices scenario, we have to create some event driven mechanism, some message brokers and event buses, that will allow maintaining async communication between different microservices, i will cover that part in my next post
public interface IQueryService { Task<IEnumerable<OrderItem>> GetNewOrders(); Task<IEnumerable<dynamic>> GetNewOrdersAsync(); Task GetNewOrders(DateTime startDate, DateTime tillDate); Task GetOrder(long orderId); }
Domain Driven Design is a model based approach, a model that can relate the business use cases, in microservices context we have business objects that are very specific to current microservice, and not to be shared with other microservices.
Now if you take the example of solution below, there I have five microservices (just for example only). The entire solution is designed to solve one big business problem like food order and delivery system, but each microservice has some specific functionality, so obvious that business entities will overlap each other, but each service will have that domain specific objects which are not shared with other service.
Remember, in this context, domain is the business problem that we are solving by designing any microservice.
As you can see in above picture, my domain model has all object definition and relationship defined, based on your project bandwidth, deployment plan and organization practice you also can split them into multiple layers like shown in left side, API layer, Domain Model Layer and Infrastructure Layer.
In my sample project I have not created any separate layers for them, put them all under one assembly only, that will not make much difference.
I will keep updating an implementation example, so that may help you to understand the domain boundaries and microservices implementation better.
You also may read
in progress