Microservice DDD Based Design
I’m Arsalan Mirbozorgi;
You should model your use cases according to business realities, according to domain-driven design (DDD). DDD refers to difficulties as domains while discussing the development of software applications. For each Bounded Context, a microservice corresponds to a separate problem area that may be discussed in a common language. Domain entities with rich models (no anemic-domain model), value objects, aggregates, and aggregate root (or root entity) rules are just a few of the technical principles and patterns that it provides. Introduces the design and execution of certain internal patterns in this part.
These DDD technical principles and patterns can be regarded as a barrier to using DDD approaches that require a steep learning curve. But what really matters is not the patterns themselves but how the code is organized and used in the context of the business challenge at hand (ubiquitous language). If you’re creating a complex microservice with important business rules, DDD methodologies should be used. A CRUD service, for example, can be handled using simpler methods.
For microservice design, it’s critical to know where you’ll draw the line. You can use DDD patterns to have a better understanding of the domain. For each Bounded Context, you identify and specify your domain’s entities, value objects, and aggregates. Within a defined framework, you construct and refine a model of your domain of expertise. A microservice is a clear example of this. Your microservices are the components that fall within those parameters, albeit a BC or business microservice is made of numerous physical services in some circumstances. Microservices, like DDD, are all about boundaries.
As much as possible, try your best to keep microservice context boundaries narrow
Two competing objectives must be balanced while determining the bounds of Bounded Contexts. While microservices may initially be modest, they should not be the primary focus; you should construct a boundary around items that require coherence. For the second time, you’ll want to keep your microservices quiet. It is possible for these aims to encounter each other. Decompose the system into as many little microservices as possible until you notice communication barriers expanding rapidly with each subsequent attempt to separate a new Bounded Context. Cohesion is critical within a single, constrained setting.
Inappropriate Intimacy is a code smell that occurs when classes are implemented. You may want to use the same microservice if two microservices need to collaborate often.
This can also be referred to as self-determination. An autonomous microservice is one that doesn’t rely on another service to fulfill a request.
DDD microservices have several layers to them
Many large-scale business and technology applications have numerous levels of abstraction. No matter how the service is deployed, the layers are a logical construct. Code complexity necessitates the existence of these tools. This necessitates translations between different kinds since distinct layers (such as domain model versus presentation) may have different types.
For instance, a database entity could be imported. A REST Web API can then be used to send some or all of that data to the client’s UI, along with additional data from other sources. Domain entities should not be transmitted outside the domain model layer, like the presentation layer, because they belong in the domain model layer.
The domain model layer’s Designing validations section explains how to create always-valid entities governed by aggregate roots (root entities). This means that client views should not be tied to entities, as some data may still be invalidated at the UI level. The ViewModel exists for precisely this purpose. For the display layer, the ViewModel is a specialized data model. The ViewModel is not directly responsible for the domain entities. In place of this, you’ll need to translate between ViewModels and domain entities and the other way around.
A domain model managed by aggregate roots ensures that all invariants and rules connected to a group of entities (aggregate) are performed through a single entry-point or gate, the aggregate root.
Figure 7-5 depicts how the eShopOnContainers application implements a tiered design.
Layers of DDD
DDD microservices like Ordering have three layers. There is a VS project for each layer: Ordering is the application layer. Domain and API layers are ordered—an orderly domain and infrastructure layer Infrastructure. According to your design, each layer of the system should only be able to communicate with a subset of the other layers. If layers are implemented as separate class libraries, it may be easier to enforce this strategy since you can clearly define the dependencies between the libraries. There should be no dependency between the domain model and any other layer (the domain model classes should be Plain Old CLR Objects, or POCO, classes). Figure 7-6 depicts the hierarchy. Any custom libraries, such as a data library or persistence library, are not required by the domain layer library, which only relies on the.NET libraries or NuGet packages.
(When layers are implemented as libraries, the dependencies between them can be better controlled)
The domain model layer
Eric Evans’s outstanding book Domain Driven Design makes these assertions regarding the domain model and application layers.
Domain Model Layer: This layer is responsible for storing information about the current business scenario and defining the business rules that govern it. Even though the infrastructure handles the technical elements of keeping the state, the business situation is managed and used here. Business software relies on this layer for its core functionality.
A company’s essence is encapsulated in the domain model layer. Layers of the domain entities that capture data and action are coded in the form of class libraries when using.NET to construct a microservices domain model (methods with logic).
The Persistence Ignorance and Infrastructure Ignorance principles dictate that this layer ignores any information about how long a file will be stored. The infrastructure layer is best suited to handle these persistence-related responsibilities. As a result, your domain model entity classes should be POCOs, which means that this layer should not directly link to the network architecture.
Any data access infrastructure framework, such as Entity Framework or NHibernate, should not directly depend on domain entities (such as deriving from a base class). No infrastructure framework type should be derived or implemented by any domain entity.
Entity Framework Core and other modern ORM frameworks like it offer this technique, such that your domain model classes are not tied to the underlying database. However, using Actors and Reliable Collections in Azure Service Fabric, it is not always viable to have POCO entities.
Although it is essential to follow the Principle of Persistence Ignorance for your current Domain model, you should not overlook the persistence considerations. Understanding the physical data model and how it corresponds to your entity object model is still critical. Otherwise, you run the risk of facing illogical designs.
This doesn’t mean that you can take a relational database model and migrate it to a NoSQL or document-oriented database without any modifications. The model may work with some entity models, although this is not always the case. Entity models are still subject to limitations imposed by storage and ORM technologies.
The application layer
Let’s examine the application layer, Evans’ book DDD can be cited once more:
Directs expressive domain objects to work out difficulties in accordance with the software’s job description. What this layer does directly impacts how the business operates or how it interacts with other application layers. This layer is kept at a minimum thickness to avoid clogging the pores. No business rules or information are contained here; just the coordination of tasks and delegation of work to domain object collaborations in the next layer below is. Even though the business scenario is not shown, it has a state that can indicate how far an individual user or a program has come in accomplishing a goal.
ASP.NET Core Web API is the most common way to implement a microservice’s application layer in.NET. Remote network connectivity and external Web APIs utilized by the user interface or client apps are all implemented as part of this project. CQRS queries, microservice commands, and even event-driven communication between microservices are all included (integration events). There should be no business rules or domain knowledge contained in ASP.NET Core Web API, which represents the application layer. Instead, these should be held by the domain model class library. No domain state or context should be held or defined by the application layer (domain model). Domain model classes (aggregate roots and domain entities) are responsible for executing business rules, which in turn change the data in those domain entities.
In short, the application logic is where all of the use cases that are dependent on a specific front end are implemented. The implementation of a Web API service, for instance.
The data model and business rules must be totally separate from the presentation and application layers of a system’s domain model. Most importantly, no infrastructure framework should be directly reliant on the domain model layer.
The foundational layer
The persistence of data initially stored in domain entities (in memory) is accomplished through the infrastructure layer. Repository pattern classes that use DBContext to store data in a relational database can be implemented using Entity Framework Core code.
Based on the previously examined Ignorance of Infrastructure and Principles of Persistence Ignorance, infrastructure must not in any way “contaminate” the layer of domain model. Your domain model entity classes must be independent of the frameworks that you use to store data (EF or any other framework) in order to keep the model independent of the data storage infrastructure. POCO entity classes are all that’s needed in your domain model layer class library; they’re the guts of your software, disconnected from any infrastructure technologies.
Rather than the other way around, as seen in Figure 7-7, your class libraries and layers should depend on your domain model layer (library).
A DDD service has three layers of dependencies: the Application layer, the Domain layer, and the Infrastructure layer. However, the Domain layer does not depend on any layer. Each microservice should have its own layer design. Following DDD patterns, it is possible to construct the most complicated microservices while implementing simple data-driven microservices (CRUD in a single layer) more easily.